DEV Community

Boehner
Boehner

Posted on • Originally published at snapapi.tech

I stopped babysitting Puppeteer — here's what I use instead

Every serious Node.js project I've worked on has eventually needed to take a screenshot of a URL, or pull the OG tags off a page, or check what tech stack a competitor is running.

Here's the cycle I kept living:

  1. Launch a browser with puppeteer.launch()
  2. Ship it. Works great.
  3. Three weeks later: Error: Target closed. Browser crashed.
  4. Add retry logic.
  5. Memory climbs to 600MB, process dies.
  6. Add a concurrency limiter.
  7. 50 URLs at once. Browser freezes.
  8. Add a queue.
  9. Repeat.

By the end, the quick screenshot utility is 300 lines and a full-time maintenance job.

What I actually needed

Simple: give me a screenshot of this URL. Works on JS-rendered pages. Doesn't crash. Doesn't cost $49/month.

The Puppeteer version:

const puppeteer = require('puppeteer');
async function screenshot(url) {
  const browser = await puppeteer.launch({ args: ['--no-sandbox'] });
  try {
    const page = await browser.newPage();
    await page.setViewport({ width: 1280, height: 800 });
    await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 });
    return await page.screenshot({ fullPage: false });
  } finally {
    await browser.close();
  }
}
Enter fullscreen mode Exit fullscreen mode

This is the happy path. No crash handling, no concurrency, 300ms cold start per call.

The SnapAPI version:

const res = await fetch(
  `https://snapapi.tech/v1/screenshot?url=${encodeURIComponent(url)}`,
  { headers: { 'x-api-key': process.env.SNAPAPI_KEY } }
);
const buffer = Buffer.from(await res.arrayBuffer());
Enter fullscreen mode Exit fullscreen mode

Three lines. Browser management, crash recovery, and concurrency all happen on their side.

The endpoint I use most: /v1/analyze

One call returns: page type, primary CTA, detected technologies, OG metadata, load time, word count — and optionally a screenshot in the same response.

const data = await fetch(
  'https://snapapi.tech/v1/analyze?url=https://stripe.com&screenshot=true',
  { headers: { 'x-api-key': process.env.SNAPAPI_KEY } }
).then(r => r.json());

console.log(data.page_type);    // "product landing page"
console.log(data.primary_cta);  // "Start now"
console.log(data.technologies); // ["React", "Next.js", "Cloudflare"]
Enter fullscreen mode Exit fullscreen mode

I built a lightweight competitor tracker with this — a cron job that checks sites every Monday and alerts when CTAs or tech stacks change. 40 lines total.

Pricing

  • Free: 100 calls/month, no credit card
  • $9/month: 1,000 calls + PDF generation + batch processing
  • $29/month: 5,000 calls (what I use)

The honest caveat

Not a replacement for Puppeteer when you need real browser automation — logins, form fills, multi-step flows. Where it wins: read-only browser work. That covers ~90% of my actual Puppeteer usage.

Free API key at snapapi.tech — no credit card, active in 30 seconds.

Top comments (0)