Take Website Screenshots in Node.js: A Complete Tutorial

F
Francesco · ScreenshotAPIs April 17, 2026 · 2 min read

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

Tired of the setup? Try the API free.

100 renders / month, no credit card. Or buy credits one-time and use them whenever — credits never expire.

Start free →
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