Puppeteer Screenshot as WebP: Format and Quality Options
Save Puppeteer screenshots as WebP with the right format and quality options. Includes runnable code, troubleshooting, and a browser-free API alternative.
To save a Puppeteer screenshot as WebP, set type: 'webp' in page.screenshot(). You can optionally set quality to a number from 0 to 100; that option does not apply to PNG. Puppeteer’s documented default screenshot type is PNG, so specify WebP explicitly when that is the format you need. The API also infers the type from the file extension, but setting both type and a matching .webp path makes the output unambiguous. Puppeteer ScreenshotOptions reference
Save a page screenshot as WebP
Install Puppeteer in a Node.js project if it is not already installed:
npm install puppeteer
Then create a file such as screenshot.mjs and run it with Node.js:
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
await page.screenshot({
path: 'capture.webp',
type: 'webp',
quality: 80,
fullPage: true,
});
} finally {
await browser.close();
}
The example saves a full-page capture. Set fullPage: false or omit that option for a viewport screenshot. The quality value of 80 is only an example; Puppeteer’s API documents the range, not a universally best setting or a guaranteed file size.
Format and quality options
| Option | What it does | Practical note |
|---|---|---|
type |
Selects png, jpeg, or webp. |
Set 'webp' explicitly for WebP. The documented default is PNG. |
quality |
Accepts a number from 0 to 100 for supported lossy image formats. | It is not applicable to PNG. The API does not prescribe a best WebP value. |
path |
Writes the screenshot to a file. | Puppeteer can infer the format from the extension. Use a .webp suffix when relying on inference. |
fullPage |
Captures the full page rather than only the viewport. | Long pages can take longer to render and produce larger images. |
The binary form of page.screenshot() returns a Uint8Array, which is useful when you want to upload or process the image instead of writing it directly to a file. Puppeteer also documents a base64 overload. For a normal file, path is the simplest option. Page.screenshot API
Choose a quality value
The permitted quality range is 0–100. The reference does not publish file-size measurements or image comparisons for particular values. Choose a value by comparing representative pages from your own rendering setup against your visual requirements and storage or transfer limits. Keep the format and quality fixed when comparing outputs so the results are meaningful.
Quality is not a PNG setting. If you need lossless-style PNG output, omit quality and use type: 'png'. If you need WebP, use type: 'webp' and optionally provide a quality value.
Screenshot an element as WebP
Puppeteer’s element screenshot method accepts screenshot options as well. Find the element, then call screenshot() with the WebP format:
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com');
const card = await page.waitForSelector('.product-card');
if (!card) throw new Error('Product card was not found');
await card.screenshot({
path: 'product-card.webp',
type: 'webp',
quality: 85,
});
} finally {
await browser.close();
}
ElementHandle.screenshot() inherits screenshot options. The selector must match an element on the page; waiting for it avoids trying to capture before it appears. Puppeteer screenshot guide
Use the screenshot bytes instead of a file
When another function or service should receive the image, omit path and handle the returned bytes. This example writes the bytes itself:
import { writeFile } from 'node:fs/promises';
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com');
const bytes = await page.screenshot({ type: 'webp', quality: 80 });
await writeFile('capture.webp', bytes);
} finally {
await browser.close();
}
The returned value is binary image data. Preserve it as bytes when uploading or saving; converting it to a UTF-8 string can corrupt the image.
Version compatibility
Puppeteer’s changelog records WebP screenshot support in version 10.4.0, released September 21, 2021. Version 20.8.0, released July 6, 2023, added WebP to the screenshot quality allow list. The current API reference documents WebP and the quality option. Check the documentation and installed package version when maintaining an older project. Puppeteer changelog
Common problems and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| The output is PNG instead of WebP. | The screenshot type was omitted, leaving the documented PNG default, or the path extension selected another format. | Set type: 'webp' and use a matching .webp filename. |
| Puppeteer rejects the quality option. | The installed version may predate WebP quality support, or the option may be used with an unsupported format. | Check the installed Puppeteer version; WebP quality was added to the allow list in 20.8.0. Do not set quality for PNG. |
| The screenshot is unexpectedly large or visually poor. | Quality is a tradeoff and results vary by page content. Full-page captures also contain more pixels than viewport captures. | Compare several quality values on representative pages. Reduce the captured area or image dimensions if appropriate for your use case. |
| The element screenshot fails because no element was found. | The selector did not match, or the element had not rendered yet. | Check the selector and use waitForSelector(); handle a missing result explicitly. |
| The page capture is incomplete. | Navigation completion does not necessarily mean all delayed or lazy content is visible. | Choose an appropriate page.goto() wait condition and, where needed, wait for the relevant selector or page-specific content before capturing. |
| The browser stays open after an error. | Execution failed before the close call. | Put browser.close() in a finally block, as in the examples. |
Performance, reliability, and cost
WebP format and quality settings determine the image output; they do not make page navigation or browser rendering instantaneous. For repeated captures, reuse a browser process where your application architecture allows it, create pages for individual jobs, and close pages and browsers when finished. Put time limits around navigation and your overall capture job, and handle navigation errors so a failed page does not prevent cleanup.
Full-page screenshots and large viewports require more rendering and image data than smaller captures. Choose the smallest capture area that meets the task. If output size matters, compare actual files from representative pages; the Puppeteer reference gives no fixed size reduction or benchmark for any quality value.
Running Puppeteer means managing a browser runtime, its lifecycle, page readiness, and failures yourself. Costs depend on where you run the browser and how you allocate compute; Puppeteer’s cited API reference does not specify hosting costs. For a production workflow, track failed navigations, timeouts, output format, and capture duration in your own system.
Or skip the browser setup
If you want a screenshot without installing and managing Puppeteer, ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots, and every response identifies the page verdict and billing status. One thousand screenshots a month are free with no card; paid plans start at $5 for 3,000.
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-o shot.webp
For setup details and options, see the ScreenshotNeo documentation. The same endpoint can be called from Python or Node.js:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);
Create a free ScreenshotNeo account for 1,000 screenshots a month with no card.
FAQ
Does Puppeteer support WebP screenshots?
Yes. The documented screenshot format options include PNG, JPEG, and WebP.
Is quality 100 the best setting?
Not necessarily. The API permits 0–100 but does not define a universally best value. Compare captures from your own pages and choose based on the result you need.
Can I set quality for PNG?
No. Puppeteer documents quality as not applicable to PNG images.
Can I capture only one element?
Yes. Use ElementHandle.screenshot() with the same type and optional quality settings.


