Take Website Screenshots in Node.js: A Complete Tutorial

April 17, 2026

Taking screenshots in Node.js usually means wrestling with Puppeteer: installing Chromium, managing browser instances, dealing with memory leaks. This guide shows you a simpler approach that works from any Node.js environment — including AWS Lambda, Vercel, and Cloudflare Workers.

Install the SDK

npm install screenshotapis

That's the only dependency. No Chromium download, no system libraries, no Dockerfile changes.

Your first screenshot

import Client from "screenshotapis";

const client = new Client("sk_live_your_key");

const { data } = await client.screenshot({
  url: "https://example.com",
  format: "png",
  full_page: true,
});

import { writeFileSync } from "fs";
writeFileSync("screenshot.png", data);

That's the complete example. The SDK handles authentication, request serialization, and returns a Buffer you can write to disk or stream to S3.

Common patterns

Screenshot a user-provided URL safely

If you're letting users input URLs (e.g., link previews in a chat app), the API automatically rejects internal IPs and localhost to prevent SSRF attacks. You don't need to add your own validation.

app.post("/preview", async (req, res) => {
  const { url } = req.body;
  try {
    const { data } = await client.screenshot({ url, format: "webp" });
    res.type("image/webp").send(data);
  } catch (err) {
    res.status(400).json({ error: "Could not render URL" });
  }
});

Generate OG images from templates

Send HTML instead of a URL to render dynamic social media preview cards:

const html = `
  <div style="width:1200px;height:630px;background:#1e3a8a;color:#fff;
              display:flex;align-items:center;justify-content:center;
              font-family:system-ui;font-size:48px">
    ${postTitle}
  </div>
`;

const { data } = await client.screenshot({
  html,
  selector: "div",
  device_scale_factor: 2,
});

Async rendering with webhooks

For large full-page screenshots or batch jobs, use webhook callbacks to avoid blocking:

await client.screenshot({
  url: "https://huge-page.com",
  full_page: true,
  webhook_url: "https://your-app.com/webhooks/screenshot",
});
// Returns immediately with 202 Accepted
// Your webhook receives the result when rendering completes

Works on serverless out of the box

Because there's no browser to launch, this works on platforms where Puppeteer doesn't — or requires special builds:

Performance tips

Start capturing screenshots in Node.js — no browser needed

Get your API key — free