Chrome DevTools can screenshot a page. Here's where it stops.
Open DevTools, press Cmd/Ctrl + Shift + P, type "screenshot",
pick Capture full size screenshot. You get a PNG of the
whole page, including the part below the fold, in about three seconds and
for nothing.
That is a good tool. If you need a picture of one page, right now, stop reading — nothing in this post will serve you better. We sell a screenshot API and we still use DevTools for this several times a week.
What follows is the honest version of where it stops: the specific points where the manual capture quietly becomes the wrong tool, in the order most teams hit them.
What DevTools actually gives you
Worth being precise, because it is more capable than people assume:
- Capture full size screenshot — the entire scrollable page, not just the viewport.
- Capture node screenshot — a single element, selected in the Elements panel.
- Capture area screenshot — a dragged rectangle.
- Device toolbar (
Cmd/Ctrl + Shift + M) — set a viewport, emulate a phone, change the device pixel ratio before you capture.
Firefox has its own equivalent, and both are free, instant, and require no account. For a bug report, a design review or a quick archive, this is the whole answer.
1. The same page screenshots differently on different machines
This is the one that surprises people, and it is the reason manual captures and visual regression testing do not mix.
Font rendering is not the same across operating systems. Antialiasing, hinting and subpixel positioning differ between macOS, Windows and Linux, and the fonts physically installed differ too — a CSS stack that falls back to a system font resolves to something else on a CI runner than on your laptop. The page is identical. The pixels are not.
So a baseline captured on your Mac and compared against a capture from a Linux build agent produces diffs on every block of text, drowning the one real change you were looking for. The fix is not a better diff algorithm; it is capturing both images in the same environment every time.
2. There is a person in the loop
Everything DevTools does requires someone to open a browser and press keys. That rules out the entire category of things you would actually want screenshots for once you have more than one:
- A check that runs on every pull request.
- A nightly capture of a page you need an audit trail for.
- An image generated when a user publishes a post.
- Monitoring a competitor's pricing page weekly.
None of these are "take a screenshot" problems. They are "take a screenshot without me" problems, and that is a different tool.
3. One page at a time
Capturing 100 URLs by hand is not a hundred times the work of capturing one — it is worse, because you also have to keep track of which ones you have done, name the files consistently, and redo the batch when something changes. The first time you need every page in a sitemap, the manual route has already stopped being viable.
4. Pages behind a login, repeatedly
DevTools handles this fine, once: you are already logged in. The problem is the tenth time, or the scheduled time, or the time it needs to happen on a machine where nobody has a session. Then you need cookies or headers passed deliberately, not a browser that happens to be signed in.
5. The output lands on your desktop
A manual capture produces a file in your Downloads folder. Anything downstream — a URL to embed, an object in S3, a webhook into your own system — is work you now do by hand, every time.
The middle option, which is often right
Between DevTools and a hosted API sits headless Chrome, and it would be dishonest to skip it:
chrome --headless --screenshot=out.png --window-size=1280,720 https://example.com
Or Puppeteer or Playwright for anything more involved. This is scriptable, free, runs in CI, and solves points 2 through 5 outright.
Self-hosting is the right call when:
- You are already running browsers for end-to-end tests, so the infrastructure exists and the marginal cost is near zero.
- The pages are internal and must never leave your network.
- Volume is high enough that per-capture pricing stops making sense.
It stops being the cheap option when you meet the operational tail: Chromium needs system libraries and fonts in the image, enough shared memory or it crashes in ways that look like timeouts, a concurrency limit or it exhausts the box, and a version upgrade every few weeks. None of that is hard. All of it is work that is not your product, and it arrives as pager duty rather than as a ticket.
We have written the longer version of this trade-off for Puppeteer and Playwright separately.
So: which one
| You need | Reach for |
|---|---|
| A picture of this page, now | DevTools |
| One element, or a dragged area | DevTools |
| Scripted captures, browsers already in your stack | Headless Chrome / Playwright |
| Internal pages that cannot leave the network | Headless Chrome, self-hosted |
| Identical rendering across machines and over time | A hosted API |
| Scheduled, batched or event-driven captures | A hosted API |
| Output that lands in storage or a webhook | A hosted API |
The honest summary: the value of a hosted API is not that it takes better screenshots. Given the same Chromium and the same viewport, the pixels are the same. The value is that the Chromium and the viewport are the same every time, and that nobody has to be there.
Try it without signing up
Paste a URL, get a PNG. No account, no card — and if you want it in your own code afterwards, the free tier is 100 captures a month.
Open the free toolA worked comparison
Say you want a screenshot of your pricing page on every deploy, stored somewhere a designer can look at it.
DevTools: someone remembers after each deploy, captures it, renames the file, uploads it. It works until the week they are on holiday, and the gap is invisible until you need the history.
Headless Chrome in CI: a step in the pipeline. You add Chromium to the build image, discover it needs more shared memory, pin a version, and own that image. Roughly a day to get right, then occasional maintenance.
Hosted API: one HTTP call from the pipeline, the image comes back as a URL. No browser in your build image.
For one page on one project, the first option is genuinely fine. The calculation changes at the second project, or the second person, or the first time the history matters.
Related reading
- A 503 that could not happen — what reproducing a bug across four environments looks like
- AI agents can drive a browser — the other alternative people reach for, and where it lands
- Free screenshot tool — the hosted version, no signup, in your browser
- A hosted alternative to Puppeteer — the self-host trade-off in detail
- Puppeteer vs Playwright in 2026 — if you are self-hosting, which library
- Best screenshot API in 2026 — five hosted options compared