๐Ÿ“ฆ Migration Guide

Complete Migration Guide: Puppeteer to SnapAPI

Replace 200+ lines of Puppeteer boilerplate with a single API call. This guide covers every common Puppeteer operation with side-by-side code comparisons, a migration checklist, and a real cost analysis.

๐Ÿ“… February 19, 2026 โฑ๏ธ 15 min read ๐Ÿท๏ธ Migration, Puppeteer, Developer Guide

1. Why Migrate Away from Puppeteer?

Puppeteer is powerful, but running it in production comes with significant operational overhead:

0
Servers to maintain
~80%
Less code to write
99.9%
API uptime SLA

The hidden costs of self-hosted Puppeteer:

2. Side-by-Side Code Comparisons

Every common Puppeteer operation translated to SnapAPI. Notice the difference in complexity.

Basic Screenshot

โŒ Puppeteer (22 lines)
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    headless: 'new',
    args: [
      '--no-sandbox',
      '--disable-setuid-sandbox',
      '--disable-dev-shm-usage'
    ]
  });
  const page = await browser.newPage();
  await page.setViewport({
    width: 1280,
    height: 800
  });
  await page.goto('https://example.com', {
    waitUntil: 'networkidle0'
  });
  await page.screenshot({
    path: 'screenshot.png'
  });
  await browser.close();
})();
โœ… SnapAPI (8 lines)
const res = await fetch(
  'https://api.snapapi.pics/v1/screenshot',
  {
    method: 'POST',
    headers: {
      'x-api-key': 'YOUR_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      url: 'https://example.com'
    })
  }
);

fs.writeFileSync(
  'screenshot.png',
  Buffer.from(await res.arrayBuffer())
);

Full-Page Screenshot with Dark Mode

โŒ Puppeteer (28 lines)
const browser = await puppeteer.launch({
  headless: 'new',
  args: ['--no-sandbox']
});
const page = await browser.newPage();
await page.setViewport({
  width: 1280, height: 800
});

// Force dark mode
await page.emulateMediaFeatures([
  {
    name: 'prefers-color-scheme',
    value: 'dark'
  }
]);

await page.goto('https://example.com', {
  waitUntil: 'networkidle0',
  timeout: 30000
});

await page.screenshot({
  path: 'full.png',
  fullPage: true
});
await browser.close();
โœ… SnapAPI (1 API call)
const res = await fetch(
  'https://api.snapapi.pics/v1/screenshot',
  {
    method: 'POST',
    headers: {
      'x-api-key': 'YOUR_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      url: 'https://example.com',
      fullPage: true,
      darkMode: true
    })
  }
);

// That's it. No browser management,
// no Chrome flags, no cleanup.

Mobile Device Emulation

โŒ Puppeteer
const iPhone = puppeteer.KnownDevices[
  'iPhone 15 Pro'
];
// Hope this device exists...
// Puppeteer's list is often outdated

const page = await browser.newPage();
await page.emulate(iPhone);
await page.goto('https://example.com');
await page.screenshot({
  path: 'mobile.png'
});
await browser.close();
โœ… SnapAPI
// 25 real devices always up to date
{
  "url": "https://example.com",
  "device": "iphone-15-pro"
}

// Also: iphone-15-pro-max, ipad-pro-11,
// pixel-8-pro, samsung-galaxy-s24,
// macbook-pro-16, and more.

PDF Generation

โŒ Puppeteer
const page = await browser.newPage();
await page.goto('https://example.com', {
  waitUntil: 'networkidle0'
});
await page.pdf({
  path: 'output.pdf',
  format: 'A4',
  printBackground: true,
  margin: {
    top: '1cm',
    bottom: '1cm',
    left: '1cm',
    right: '1cm'
  }
});
await browser.close();
โœ… SnapAPI
{
  "url": "https://example.com",
  "pdfOptions": {
    "pageSize": "a4",
    "printBackground": true,
    "marginTop": "1cm",
    "marginBottom": "1cm"
  }
}

// POST to /v1/pdf
// Returns PDF binary directly

Element Screenshot with Wait

โŒ Puppeteer
const page = await browser.newPage();
await page.goto('https://example.com');
await page.waitForSelector(
  '#chart-container',
  { timeout: 10000 }
);
// Extra delay for animations
await new Promise(
  r => setTimeout(r, 2000)
);
const el = await page.$(
  '#chart-container'
);
await el.screenshot({
  path: 'chart.png'
});
await browser.close();
โœ… SnapAPI
{
  "url": "https://example.com",
  "selector": "#chart-container",
  "waitForSelector": "#chart-container",
  "delay": 2000
}

// All in a single parameter.
// No browser lifecycle management.

Blocking Ads & Cookie Banners

โŒ Puppeteer (needs puppeteer-extra)
const puppeteer = require(
  'puppeteer-extra'
);
const AdblockerPlugin = require(
  'puppeteer-extra-plugin-adblocker'
);
puppeteer.use(AdblockerPlugin({
  blockTrackers: true
}));

// Cookie banners? You're on your own.
// Write custom CSS or JS to hide them.
// Or use yet another plugin.

const browser = await puppeteer.launch();
// ...
โœ… SnapAPI
{
  "url": "https://example.com",
  "blockAds": true,
  "blockTrackers": true,
  "blockCookieBanners": true,
  "blockChatWidgets": true
}

// Built-in. No plugins needed.
// Always up to date filter lists.

Batch Processing

โŒ Puppeteer (you build it yourself)
const urls = [/* 100 URLs */];
const CONCURRENCY = 5;

async function processUrl(url, browser) {
  const page = await browser.newPage();
  try {
    await page.goto(url, {
      timeout: 30000
    });
    await page.screenshot({/*...*/});
  } catch (e) {
    console.error(url, e);
  } finally {
    await page.close();
  }
}

// Build your own queue, concurrency
// limiter, retry logic, error handling
// ... 50+ more lines
โœ… SnapAPI (built-in)
{
  "urls": [
    "https://example.com",
    "https://google.com",
    // ... up to 100 URLs
  ],
  "format": "png",
  "webhookUrl": "https://you.com/done"
}

// POST to /v1/screenshot/batch
// We handle concurrency, retries,
// and notify you when done.

3. Performance Comparison

1.2s
SnapAPI avg response
3.5s
Puppeteer avg (cold)
3x
Faster on average
MetricPuppeteer (self-hosted)SnapAPI
Cold start time2-5s (browser launch)0ms (always warm)
Avg screenshot time3-5s1-2s
Memory per instance200-500MB0MB (API call)
Max concurrent5-10 per serverUnlimited (rate limited)
Reliability95-98% (crashes)99.9% SLA
Chrome updatesManualAutomatic
๐Ÿ’ก Pro tip

SnapAPI keeps browser pools warm 24/7. Your first request is as fast as your 1000th โ€” no cold starts, no browser launch overhead.

4. Cost Comparison

Let's compare the real cost of running Puppeteer yourself vs. using SnapAPI for 50,000 screenshots/month:

Cost ItemSelf-Hosted PuppeteerSnapAPI
Server (4 CPU, 8GB RAM)$40-80/moโ€”
DevOps / Monitoring$200-500/mo (time cost)โ€”
Error handling / retries$100-200/mo (dev time)โ€”
Chrome license / updatesFree but time-consumingโ€”
SnapAPI subscriptionโ€”$19/mo (Starter)
Total$340-780/mo$19/mo
โš ๏ธ Hidden costs people forget

Developer time is the biggest cost. Debugging Puppeteer memory leaks at 3 AM, handling Chrome version mismatches, and building retry logic costs far more than the server itself.

5. Migration Checklist

๐Ÿ”„ Step-by-Step Migration

โ˜Sign up for SnapAPI โ€” Get your API key from app.snapapi.pics. Free tier includes 200 screenshots.
โ˜Map your Puppeteer operations โ€” List every place in your code that uses Puppeteer. Most map directly to SnapAPI parameters.
โ˜Replace browser launch/close โ€” Remove all puppeteer.launch() and browser.close(). Replace with HTTP fetch calls.
โ˜Map viewport settings โ€” Convert page.setViewport() to width/height params, or use device presets.
โ˜Replace page.goto() โ€” The URL goes into the request body's url field. waitUntil maps directly.
โ˜Replace page.screenshot() โ€” Options like fullPage, format, quality map 1:1 to SnapAPI params.
โ˜Replace page.pdf() โ€” Use the /v1/pdf endpoint. PDF options map directly.
โ˜Replace page.evaluate() โ€” Use the javascript parameter to inject custom JS before capture.
โ˜Replace waitForSelector โ€” Use the waitForSelector parameter. Same CSS selectors work.
โ˜Remove Puppeteer dependencies โ€” npm uninstall puppeteer puppeteer-extra puppeteer-extra-plugin-adblocker
โ˜Remove Chrome from Docker/server โ€” No more 400MB+ Chrome binaries in your Docker images.
โ˜Test edge cases โ€” Test with your most complex pages. SnapAPI handles SPAs, lazy-loaded content, and dynamic pages.
โ˜Set up error handling โ€” Add retry logic for 429 (rate limit) responses. Check X-RateLimit-Remaining header.

6. Advanced Scenarios

Custom JavaScript Injection

If you use page.evaluate() to modify the page before capturing, use the javascript parameter:

SnapAPI โ€” Custom JS injection
{
  "url": "https://example.com",
  "javascript": "document.querySelector('.banner').remove(); document.body.style.background = '#fff';",
  "delay": 500
}

Authentication / Cookies

If your Puppeteer code sets cookies for authenticated sessions:

SnapAPI โ€” Authenticated screenshots
{
  "url": "https://app.example.com/dashboard",
  "cookies": [
    { "name": "session", "value": "abc123", "domain": "app.example.com" }
  ],
  "extraHeaders": {
    "Authorization": "Bearer your-token"
  }
}

Proxy & Geolocation

SnapAPI โ€” Geo-targeted screenshot
{
  "url": "https://example.com",
  "proxy": { "server": "http://proxy.example.com:8080" },
  "geolocation": { "latitude": 40.7128, "longitude": -74.0060 },
  "timezone": "America/New_York",
  "locale": "en-US"
}

7. FAQ

Can I still use Puppeteer for some things?

Absolutely. SnapAPI covers screenshots, PDFs, videos, and content extraction. If you need complex multi-step browser automation (filling forms, clicking through flows), Puppeteer or Playwright may still be the right tool. Many teams use SnapAPI for capture tasks and keep a small Puppeteer setup for automation.

What about Playwright?

Everything in this guide applies to Playwright too. The API call is identical โ€” just replace your Playwright code the same way. See our Playwright vs Puppeteer comparison.

Is there a Node.js SDK?

Yes! We have SDKs for JavaScript, Python, Go, PHP, Kotlin, and Swift. Check the documentation for installation instructions. But even without an SDK, it's just a fetch call โ€” no SDK required.

What if I need more than 50,000 screenshots/month?

Our Business plan supports up to 500,000/month, and we offer custom Enterprise plans for higher volumes. Contact us for details.

Ready to Ditch Puppeteer?

Start with 200 free screenshots. No credit card required. Most teams migrate in under an hour.

Start Free โ†’ snapapi.pics

Related Reading