Whether you need to monitor website changes, generate social previews, create PDF reports, or archive web content, taking screenshots programmatically is a common Node.js task. Here's every approach, with real code examples.
1. Puppeteer (Self-Hosted)
The most common approach, but comes with operational overhead:
npm install puppeteer
const puppeteer = require("puppeteer");
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://example.com");
await page.screenshot({ path: "screenshot.png", fullPage: true });
await browser.close();
Pros: Full control, free, customizable
Cons: Memory-hungry (400MB+), cold starts, needs a server with Chrome installed
2. Playwright (Microsoft's Puppeteer Alternative)
npm install @playwright/test
npx playwright install chromium
const { chromium } = require("playwright");
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto("https://example.com");
await page.screenshot({ path: "screenshot.png", fullPage: true });
await browser.close();
Same trade-offs as Puppeteer — great locally, painful in production.
3. Hosted Screenshot API (SnapAPI)
If you're running on serverless (Vercel, AWS Lambda) or just don't want to maintain headless Chrome:
npm install snapapi-js
import SnapAPI from "snapapi-js";
const client = new SnapAPI({
apiKey: "your-api-key", // Free tier: 100 calls/month
baseUrl: "https://api.opspawn.com",
});
// Take a screenshot
const screenshot = await client.capture("https://example.com");
// → Returns PNG buffer
// Generate a PDF
const pdf = await client.pdf("https://example.com");
// → Returns PDF buffer
Pros: No server maintenance, works in serverless, scales automatically
Cons: Costs money at scale (Pro: $19/mo for 10K calls)
Get an API key: opspawn.com/snapapi
4. Sharp + Puppeteer (Screenshots to Images)
For image processing after capture:
const puppeteer = require("puppeteer");
const sharp = require("sharp");
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://example.com");
const screenshotBuffer = await page.screenshot({ fullPage: true });
// Resize to thumbnail
const thumbnail = await sharp(screenshotBuffer)
.resize(400, 300, { fit: "cover" })
.toBuffer();
5. Browserless.io (Hosted Chrome)
Another managed option for when you need full browser control but not a full server:
const puppeteer = require("puppeteer");
const browser = await puppeteer.connect({
browserWSEndpoint: `wss://chrome.browserless.io?token=${YOUR_TOKEN}`,
});
const page = await browser.newPage();
// ... rest of your puppeteer code
When to Use Which
| Approach | Best For | Avoid When |
|---|---|---|
| Puppeteer | Local dev, full control | Serverless, cost-sensitive |
| Playwright | Testing pipelines | Production screenshot service |
| SnapAPI | Production, serverless | Need raw browser access |
| Sharp + Puppeteer | Thumbnail generation | Simple screenshots |
| Browserless | Complex interactions | Simple screenshots |
Quick Performance Comparison
A simple https://example.com screenshot:
- Self-hosted Puppeteer (cold): ~2-4s
- Self-hosted Puppeteer (warm): ~500ms
- SnapAPI: ~800ms (includes network)
For most use cases where screenshots aren't the core product, a hosted API is the pragmatic choice. For pixel-perfect control or complex interactions, self-hosted wins.
Got a screenshot use case? Try SnapAPI free — 100 calls/month with no credit card required.
Top comments (0)