Screenshot API in Node.js: Puppeteer vs PageBolt
You need to screenshot a web page in Node.js. Your first instinct: reach for Puppeteer. Install it, download Chromium (300MB), manage browser lifecycle, handle crashes. It works, but it's heavy.
There's a simpler way.
The Puppeteer way (before)
Here's what a typical Puppeteer screenshot looks like:
const puppeteer = require('puppeteer');
async function captureScreenshot(url) {
const browser = await puppeteer.launch();
const page = await browser.newPage();
try {
await page.goto(url, { waitUntil: 'networkidle2' });
const screenshot = await page.screenshot({ fullPage: true });
console.log('Screenshot taken:', screenshot);
return screenshot;
} finally {
await browser.close();
}
}
captureScreenshot('https://example.com');
This works. But:
- Cold start: 3-10 seconds for Chromium to boot
- Bundle size: 300MB+ on disk
- Memory overhead: 100-200MB per process
- Deployment pain: Can't run on Vercel edge, AWS Lambda, or lightweight containers
- Maintenance: Browser updates, crash handling, process cleanup
The PageBolt way (after)
Same task, one API call:
const PAGEBOLT_API_KEY = process.env.PAGEBOLT_API_KEY;
async function captureScreenshot(url) {
const response = await fetch('https://pagebolt.dev/api/v1/screenshot', {
method: 'POST',
headers: {
'x-api-key': PAGEBOLT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
url: url,
width: 1280,
height: 720,
format: 'png',
fullPage: true,
}),
});
const data = await response.json();
console.log('Screenshot:', data.screenshot); // base64 string
return data.screenshot;
}
captureScreenshot('https://example.com');
Done. No Chromium. No process management. No cold starts.
Why the PageBolt approach wins
| Metric | Puppeteer | PageBolt |
|---|---|---|
| Setup time | 5 minutes + 300MB download | 1 minute, 0 bytes local |
| Cold start | 3-10 seconds | <500ms |
| Bundle size | 300MB+ | 0 bytes |
| Memory per request | 100-200MB | <1MB |
| Runs on Vercel edge | ❌ | ✅ |
| Runs on Lambda | ❌ (too slow, too big) | ✅ |
| Handles JavaScript rendering | ✅ | ✅ |
| Device emulation | Limited | 25+ presets |
| Ad blocking | Manual setup | Built-in |
| Maintenance burden | High | Zero |
Real-world comparison
Scenario: Screenshot every page in a sitemap on deploy
With Puppeteer, you need:
- A separate server or Lambda with huge timeout
- Concurrent browser process management
- Memory scaling
- Chromium binary in your deployment pipeline
With PageBolt:
const urls = ['https://example.com', 'https://example.com/about', 'https://example.com/pricing'];
const screenshots = await Promise.all(
urls.map(url =>
fetch('https://pagebolt.dev/api/v1/screenshot', {
method: 'POST',
headers: {
'x-api-key': PAGEBOLT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({ url, width: 1280, height: 720, format: 'png' }),
}).then(r => r.json())
)
);
console.log('All pages screenshotted:', screenshots);
Parallel requests. No infrastructure. Done in seconds.
When to use Puppeteer
Puppeteer is still right if you:
- Need to interact with the page (fill forms, click buttons)
- Run on a dedicated server with Chromium pre-installed
- Have complex multi-step workflows that need tight control
When to use PageBolt
Use PageBolt if you:
- Just need screenshots
- Run on serverless (Vercel, Lambda, etc.)
- Want zero infrastructure management
- Need to parallelize across hundreds of pages
- Build CI/CD pipelines for visual regression
Getting started
- Sign up at pagebolt.dev (free: 100 requests/month)
- Add your API key to
.env - Replace your Puppeteer code with the snippet above
- Deploy with zero changes to your infrastructure
That's it.
Try it free: 100 requests/month, no credit card required. Get started →
Top comments (0)