Puppeteer Alternative

Drop Puppeteer.
Keep the output quality.

Replace your Puppeteer screenshot code with a single fetch call. Same pixel-perfect rendering, zero binary dependencies, deploys anywhere Node.js runs.

Start Free — 100 renders/mo View API Docs
Migration

Before & after — a one-function swap

Your existing HTML templates stay unchanged. Only the render function changes.

✕  Before — Puppeteer
import puppeteer from 'puppeteer'

async function renderToImage(
  html: string
): Promise<Buffer> {
  // Launch a new browser every call
  const browser = await puppeteer.launch({
    args: ['--no-sandbox',
           '--disable-dev-shm-usage']
  })
  const page = await browser.newPage()
  await page.setViewport({
    width: 1200, height: 630
  })
  await page.setContent(html, {
    waitUntil: 'networkidle0'
  })
  const buf = await page.screenshot({
    type: 'png'
  })
  await browser.close()
  return buf as Buffer
}

// ~300 MB Chromium binary in bundle
// 2-4 s cold start on Lambda
// Crashes on Vercel (250 MB limit)
✓  After — RenderPix
async function renderToImage(
  html: string
): Promise<Buffer> {
  const res = await fetch(
    'https://api.renderpix.dev/v1/render',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization':
          `Bearer ${process.env.RENDERPIX_KEY}`,
      },
      body: JSON.stringify({
        html, width: 1200, height: 630
      }),
    }
  )
  const { url } = await res.json()
  const img = await fetch(url)
  return Buffer.from(
    await img.arrayBuffer()
  )
}

// 0 MB added to bundle
// ~200 ms response time
// Deploys on Vercel, Lambda, anywhere
Impact

What changes after migration

0 MB
Added to your bundle
(vs ~300 MB for Chromium)
~200ms
Median render time
(vs 2–4 s cold start)
< 5 min
Migration time
one function, same interface
Comparison

RenderPix vs Puppeteer vs Playwright vs Browserless

All four options use real Chromium rendering — the difference is who manages the browser.

Tool Bundle size Serverless deploy Cold start Maintenance TypeScript
RenderPix 0 MB Yes ~200 ms None Yes
Puppeteer ~300 MB No 2–4 s High Yes
Playwright ~300 MB No 2–4 s Medium Yes
Browserless.io 0 MB Yes ~800 ms Low Yes
FAQ

Common questions

How long does migration take?

For most codebases, under 5 minutes. You replace one function — the part that launches a browser and takes a screenshot. Your HTML templates, image sizes, and everything downstream stay exactly the same. The before/after code above is the complete change for the common case.

Is the output quality the same as Puppeteer?

Yes. RenderPix uses the same headless Chromium engine as Puppeteer — the rendering is identical. Custom fonts, CSS gradients, grid layouts, clip-path, backdrop-filter — anything Chrome renders, we capture. The PNG output is pixel-for-pixel the same as a local Puppeteer screenshot at the same viewport size.

Is there TypeScript support?

The API is a plain HTTP endpoint, so it works with TypeScript out of the box — no additional types needed. The function in the "After" example above is fully typed. If you want request/response types for autocomplete, they're documented in the API docs.

What happens to waitUntil: 'networkidle0'?

RenderPix handles this automatically. The renderer waits for fonts, images, and stylesheets to finish loading before capturing. You don't need to configure a wait condition — just send the HTML and the returned image will be fully rendered.

Can I keep using Puppeteer for automation and use RenderPix only for screenshots?

Absolutely. If you use Puppeteer for form filling, scraping, or other browser automation, there's no reason to change that. Just replace the screenshot-specific code paths with RenderPix API calls. The two can coexist in the same project.

Replace Puppeteer in under 5 minutes

Same rendering quality. No binary, no cold starts. Free tier, no credit card required.