Screenshot API vs Puppeteer/Playwright: when to build and when to buy
I built both sides of this equation — a Playwright renderer and a screenshot API on top of it. Most "build vs buy" articles are written by API vendors pushing you to buy. This one walks through the real problems (lazy loading, cookie banners, memory, timeouts), gives you honest thresholds for when each approach wins, and lets you decide.
I thought long and hard about whether to write this at all. You might think I can't be objective here, since I built a screenshot API myself and obviously want you to pick my product. But it's actually the opposite.
Because I built everything from scratch on Playwright, I had to figure out the entire process myself. Cookie banners, lazy loading, pages that hang forever, server configuration, memory leaks in headless Chrome. I went through all of it, and now I can tell you what you'll run into on either path. Then you decide.
Playwright in 5 minutes: why it feels easy
Here's the minimum code to take a screenshot with Playwright:
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({ path: 'screenshot.png' });
await browser.close();
})();
Eight lines and you have a screenshot. It works. On example.com.
The thing is, example.com is probably the simplest website on the internet. The moment you start screenshotting real pages, questions come up that those eight lines don't answer.
What breaks when you move from example.com to real websites
Here's a list of problems I ran into personally while building ScreenshotRun. Not theoretical ones. These are things I had to solve in production.
Lazy-loaded images. Most modern sites don't load images until the user scrolls near them. Playwright doesn't scroll by default, so the bottom half of a full-page screenshot ends up as grey rectangles. I wrote a detailed breakdown of this problem in my post about lazy loading and grey boxes.
Cookie banners. About half the sites out there greet you with a GDPR popup covering the content. You need to either click "Accept" or hide the banner with CSS. There's no universal fix because every site implements its banner differently.
Timeouts and hangs. Some pages never reach networkidle. Ad networks, analytics scripts, WebSocket connections, endless polling requests. Without proper timeout handling, your script just sits there.
Fonts. Custom fonts might not finish loading before the screenshot fires. You end up with text rendered in a fallback font, or worse, invisible text while the browser waits for the font file (FOIT).
Memory. A single headless Chrome instance eats about 300MB of RAM. Five parallel screenshots and you're at 1.5GB. On a cheap VPS, that becomes a problem fast.
Browser updates. Playwright ships with a specific browser version. After an update, things can shift: different rendering, changed behavior, broken APIs you relied on.
Every one of these problems is solvable. I solved them all when building my service. But each solution is code you need to write, test, and maintain going forward.
When Playwright is the right call
Not everyone needs an API. Here are situations where Playwright (or Puppeteer, the differences are minimal for screenshots) makes sense:
You're screenshotting a few specific pages you control. Your own dashboard, your landing page after a deploy, your admin panel for reports. You know the structure of these pages. You can write a waitForSelector for the exact element, you know which fonts load, there are no cookie banners. Playwright works great here, and paying for an API would be a waste.
You already run Playwright for something else. If your project already has a headless browser for testing or scraping, adding screenshots on top is minimal effort. The infrastructure is already there.
You need something non-standard. Log into a page, go through a sequence of steps, fill out a form, then take a screenshot. Ready-made APIs support some of this, but if the scenario is complex, your own script gives you full control.
The volume is small and not mission-critical. A dozen screenshots a day for internal use? Playwright running on the same machine as your app will handle that without breaking a sweat.
When an API starts to win
And here are situations where your own Playwright stack starts costing more than it looks like on paper:
Variety of sites. The moment you're screenshotting other people's websites, you lose control over the page structure. Cookie banners, lazy loading, popups, slow CDNs, unusual fonts. Each site can break your script in a new way. I spent weeks getting my renderer to work reliably across different sites, and I still find edge cases.
Volume is growing. At 10 screenshots a day, Playwright runs fine on any server. At 1,000 a day, you need to think about job queues, concurrency limits, memory monitoring, restarting hung processes. That's an infrastructure problem, not a five-line-code problem.
Reliability matters. If the screenshot goes into a client report, into visual regression checks in CI, into competitor monitoring, one missed or broken capture is a real problem. With Playwright on your own server, you're the one building retry logic, alerts, and fallback handling.
Developer time is expensive. You can set up Playwright in an hour. Setting up a Playwright stack that works reliably on 95% of sites without babysitting takes weeks. I know, because I did it. The question is whether that time is worth more than $10-50 per month for a ready-made API.
The real cost: Playwright vs API
Worth doing the math. Playwright is free, but the server isn't.
The cheapest VPS that runs headless Chrome reliably costs about €7-15/month (Hetzner CPX21-CPX31). You can run 3-5 renders in parallel without memory issues. That covers roughly 2,000-5,000 screenshots per day, not counting development time.
Compare that to APIs:
ScreenshotRun's free tier gives you 300 requests per month. Paid plans start at $10/month. Competitors start at roughly $17-39/month for their entry-level plans.
If you only count server costs, Playwright is cheaper. But add in the cost of development time, debugging, maintaining scripts, and handling edge cases, and the picture changes. One day of debugging a script that broke on a specific site costs more in developer time than six months of an API subscription.
What I'd pick in your place
It comes down to two questions:
First: are you screenshotting your own pages or someone else's? Your own pages, you control. You can write a precise script. For other people's sites, you need flexibility and handling for the unexpected.
Second: are screenshots the core of your product or a supporting feature? If they're core (like they are for me), it makes sense to build and optimize your own setup. If they're supporting (thumbnails for a directory, snapshots for reports, post-deploy monitoring), it's simpler to outsource and move on.
If both answers are "someone else's" and "supporting," an API will almost certainly save you money and headaches. If both are "my own" and "core," Playwright gives you maximum control.
In-between cases depend on volume. Under 100 screenshots a day on your own server, Playwright is probably simpler. Over 500 a day across a variety of sites, it's worth looking at an API.
How to try both approaches
If you want to start with Playwright, I have tutorials with working code: screenshots with Node.js, with Python, with PHP, with Go, and even just with cURL.
If you want to try the API approach with no commitment, ScreenshotRun gives you 300 free requests per month. Enough to see whether an API fits your use case. All the dirty work I talked about above (lazy loading, cookie banners, timeouts, font loading) is already handled.
If you end up deciding Playwright is your thing, the tutorials and code aren't going anywhere. And if not, you won't have to spend a week arriving at the same conclusion on your own.
Vitalii Holben