What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Use await page.screenshot({ path: 'screenshot.png' }) when you want Puppeteer to write an image file. Omit path when the next step needs image bytes in memory: Puppeteer returns a Uint8Array. Set encoding: 'base64' when the receiving system specifically expects a Base64 string.
Choose the output form first
Puppeteer has three practical screenshot-data paths. They produce the same captured image, but they fit different parts of an application.
| Need | Puppeteer call | Result |
|---|---|---|
| A file on disk | page.screenshot({ path: 'shot.png' }) |
The image is written directly to the named path; the extension determines the format. |
| Binary data for immediate processing or upload | const data = await page.screenshot() |
A Uint8Array containing the encoded image. |
| Text-safe data for JSON, HTML or a text-only API | const data = await page.screenshot({ encoding: 'base64' }) |
A Base64 string. |
The current Page API reference consulted for these calls is labeled Puppeteer 25.12.0. Check the API documentation that matches your installed package when upgrading, because signatures and compatibility can change between versions.
Save a screenshot directly to a file
Minimal Node.js example
Install Puppeteer, launch a browser, navigate to a URL, and provide a writable path:
#1 Best Overall
- Get NVMe solid state performance with up to 1050MB/s read and 1000MB/s write speeds in a portable, high-capacity drive(1) (Based on internal testing; performance may be lower depending on host device & other factors. 1MB=1,000,000 bytes.)
- Up to 3-meter drop protection and IP65 water and dust resistance mean this tough drive can take a beating(3) (Previously rated for 2-meter drop protection and IP55 rating. Now qualified for the higher, stated specs.)
- Use the handy carabiner loop to secure it to your belt loop or backpack for extra peace of mind.
- Help keep private content private with the included password protection featuring 256‐bit AES hardware encryption.(3)
- Easily manage files and automatically free up space with the SanDisk Memory Zone app.(5). Non-Operating Temperature -20°C to 85°C
npm install puppeteer
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
await page.screenshot({ path: 'screenshot.png' });
} finally {
await browser.close();
}
})();
If the path ends in .png, .jpg or .webp, Puppeteer infers that format. With no explicit type, PNG is the documented default. The directory must already exist and the process must have permission to create or replace the file.
Control format, dimensions and page coverage
await page.screenshot({
path: 'full-page.webp',
type: 'webp',
fullPage: true,
quality: 82
});
fullPage: truecaptures the full scrollable page instead of only the current viewport. It defaults tofalse.typeselects PNG, JPEG or WebP where supported by your Puppeteer version. The filename extension alone is enough for common cases.qualityaccepts 0–100 for lossy formats. It has no effect on PNG.omitBackground: trueremoves the default white background so transparent output is possible.
Capture only a rectangle
Pass a clip rectangle when you need a fixed region rather than an element:
await page.screenshot({
path: 'header.png',
clip: { x: 0, y: 0, width: 1200, height: 180 }
});
The rectangle uses page coordinates. Make sure its dimensions fit the page and viewport you configured; a mistaken coordinate can produce an empty or unexpected region. The documented captureBeyondViewport default is false without a clip and true with a clip.
Keep the image data in memory
Use the default Uint8Array
When path is omitted, Puppeteer does not save anything to disk. Retain the returned value and pass it to a file writer, an HTTP client, an object-storage SDK or an image-processing library.
const imageData = await page.screenshot(); // Uint8Array
// Node.js can write a Uint8Array directly.
const fs = require('node:fs/promises');
await fs.writeFile('memory-output.png', imageData);
This binary form avoids adding a text representation when your next API accepts bytes. It is also the right form for multipart uploads or a response body that should have an image content type.
Return Base64 when a text value is required
const imageBase64 = await page.screenshot({ encoding: 'base64' });
const dataUrl = `data:image/png;base64,${imageBase64}`;
console.log(dataUrl.slice(0, 40));
Base64 is useful for JSON fields, HTML data URLs and systems that cannot carry binary data. It is larger than the underlying bytes, so do not convert to Base64 merely because a byte upload is available.
Rank #2
- Solid state performance with up to 800MB/s read speeds in a portable drive. (Based on internal testing; performance may be lower depending on host device, interface, usage conditions and other factors. 1MB=1,000,000 bytes.)
- Back up your content and memories on a storage solution that fits seamlessly into your mobile lifestyle.
- Take it with you on your adventures—up to two-meter drop protection means this durable drive can take a beating. (Based on internal testing.)
- Secure it to your belt loop or backpack for extra peace of mind thanks to the tough rubber hook.
- From Sandisk, a brand professional photographers trust to take on assignments.
Decode Base64 back to a file
const fs = require('node:fs/promises');
const base64 = await page.screenshot({ encoding: 'base64' });
await fs.writeFile('decoded.png', Buffer.from(base64, 'base64'));
Save one element instead of the whole page
Use an element handle when the required image is a card, chart, invoice or other component. Puppeteer’s element helper scrolls the element into view if necessary.
const element = await page.waitForSelector('.target');
if (!element) throw new Error('Target element was not found');
await element.screenshot({ path: 'element.png' });
A detached element handle causes an error. Dynamic applications can replace a node after it is found, so locate the element as close as possible to the screenshot call, wait for the component’s stable state, and retry with a fresh handle if the framework re-renders it.
Make the capture deterministic
Wait for the content you actually need
waitUntil: 'networkidle2' in page.goto() is useful for pages that finish loading after their initial HTML, but it does not guarantee that a chart, animation or lazy image is ready. Add an explicit selector wait or a short, justified delay:
await page.goto('https://example.com/report', { waitUntil: 'domcontentloaded' });
await page.waitForSelector('#report-chart');
await page.screenshot({ path: 'report.png', fullPage: true });
For animations, disable them with page-level CSS before capture when visual stability matters:
await page.addStyleTag({
content: '* { animation: none !important; transition: none !important; }'
});
Set a known viewport and device scale
await page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 1 });
A fixed viewport makes repeated captures comparable. A higher device scale factor produces more physical pixels and therefore larger image data. Choose it deliberately rather than assuming a screenshot’s CSS dimensions equal its pixel dimensions.
Handle pages that lazy-load images
For a full-page image, scroll or otherwise trigger lazy content before calling screenshot(). If the page’s own code only loads images near the viewport, a single initial screenshot can contain placeholders. Waiting for the image selectors and checking their complete state is safer than relying on a global network-idle event.
Rank #3
- Capacity Display Variance: 500GB external ssd often appears as around 465GB on Windows. MacOS can show full 500 GB capacity. This is binary calculation difference and doesn’t affect SSD hard drive actual physical storage
- 1050 MB/s Speed: Instantly access to your files with blazing-fast 10Gbps external SSD read up to 1050MB/s and write up to 1000MB/s. LED Light indicates USB SSD instant activity
- Data Security: Solid state drives S.M.A.R.T. health diagnostics and adaptive TRIM optimizing data block management ensures consistent write speeds and extends the longevity of the portable SSD
- USB-C & USB-A Cable: Both cables featuring rapid USB 3.2 Gen2, this USB SSD effortlessly bridges devices, enabling seamless cross-platform file transfers and backup between computers, smartphones, tablets and iPhone
- Always Fast: No slowdowns for large file transfers. With SLC caching (25% of current available capacity allocated as high-speed cache), this external SSD delivers steady 10Gbps for transfers within the cache capacity
Lifecycle, reliability and resource notes
- Keep the browser and page open until the screenshot promise resolves. In a BrowserContext,
newPage()andPage.close()wait for an active screenshot to finish;Page.bringToFront()does not wait for one. - Use
try...finallyto close the browser on success and failure. This prevents abandoned Chromium processes when navigation or capture throws. - Full-page captures and high device-scale images require more memory than viewport captures. Prefer an element or clipped region when that is all the consumer needs.
- PNG preserves lossless detail and supports transparency. JPEG and WebP allow
qualitycontrol; PNG ignores that option. - Saving to disk incurs filesystem I/O; returning a
Uint8Arraykeeps the pipeline in memory. Select the form required by the next operation rather than converting repeatedly.
Puppeteer itself does not charge per screenshot. Your operational cost comes from the browser process, CPU, memory, storage and any hosting or bandwidth used to run and deliver the result.
Troubleshoot common failures
“Path does not exist” or permission errors
Create the parent directory first and use an absolute path while diagnosing. Confirm that the account running Node can write there. A filename does not create missing folders.
The output is blank or incomplete
Wait for the selector that represents finished content, allow lazy images to load, and verify that the page did not navigate to an interstitial or bot-check screen. For a viewport-only capture, use fullPage: true when content extends below the fold.
Element screenshot throws “detached”
The framework replaced the node between lookup and capture. Call waitForSelector() again, wait for the component’s final render, and capture the new handle.
Free tools Windows power users keep installed
One-click scans. No signup required.
Quality has no visible effect
quality is ignored for PNG. Select JPEG or WebP with type (and a matching extension) before tuning the value.
Base64 output is unexpectedly undefined or binary
Ensure the option is exactly encoding: 'base64' and retain the resolved value. Without that option, the documented result is a Uint8Array, not a string and not an automatically created file.
Rank #4
- NEARLY 2X FASTER THAN OUR PREVIOUS GENERATION(8) – move 1,000 high-res photos in under 60 seconds(6) with up to 2000MB/s transfer speeds(2).
- IP65 RATING AND UP TO 3M DROP PROTECTION(3) – protects against spills and drops.
- POCKET-SIZED – fits easily in pockets and small bags.
- SPACE TO OWN YOUR AI CONTENT – speed and capacity to download your high-res clips and photo edits.
- 256-BIT AES ENCRYPTION(4) – helps keep private files secure with password protection.
The capture fails during navigation
Separate navigation from capture so you can identify which promise failed. Set a realistic navigation timeout, wait for a concrete page condition, and close the browser in finally before retrying.
Or skip the browser setup
If you only need a hosted screenshot endpoint, ScreenshotNeo is the first service to try: it removes consent banners, newsletter popups and chat widgets before capture, bills only clean shots, and its paid entry plan is $5 for 3,000 shots.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →One GET request returns PNG, JPEG, WebP or PDF. The API documentation is at https://screenshotneo.com/docs/.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
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}`);
ScreenshotNeo exposes 63 capture options, including full-page and CSS-selector captures, dark mode, 12 device presets plus custom viewports, retina scale, PDF paper settings and page ranges, custom CSS and JavaScript, click-before-capture, selector hiding, selector/delay/network-idle waits, ad and tracker blocking, custom headers, cookies, user agents and Authorization, timezone and geolocation, transparent backgrounds, resizing, selectable cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, usage reporting and an OpenAPI specification. Common parameter names used by other screenshot APIs also work.
Failed bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and each response reports the result through X-Page-Verdict and X-Billed headers. An MCP server provides take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients.
| Plan | Allowance | Price |
|---|---|---|
| Free | 1,000 shots/month | $0, no card |
| Starter | 3,000 shots | $5 |
| Growth | 15,000 shots | $15 |
| Pro | 60,000 shots | $39 |
| Scale | 250,000 shots | $99 |
| Business | 1,000,000 shots | $249 |
Yearly billing provides two months free, and every feature is included on every plan. Create a free ScreenshotNeo account to get 1,000 screenshots a month without entering a card.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallFAQ
Does the file extension always control the image format?
Puppeteer uses the path extension to infer a format when you do not provide type. For unambiguous output, set both type and a matching extension, especially when producing JPEG or WebP.
Best Value
- Easily store and access 2TB to content on the go with the Seagate Portable Drive, a USB external hard drive
- Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop
- To get set up, connect the portable hard drive to a computer for automatic recognition no software required
- This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
- The available storage capacity may vary.
Is Puppeteer 25.12.0 required?
No. 25.12.0 is the version label on the consulted API reference, not a requirement to use screenshots. Check the reference that matches the version installed in your project before relying on a version-specific option.
Can I capture an element that is currently off-screen?
Yes. ElementHandle.screenshot() scrolls the element into view when needed. It still requires the handle to remain attached until the screenshot completes.
Frequently Asked Questions
What happens if I close the page while a screenshot is running?
Keep the page and browser alive until the screenshot promise resolves; closing the page first can interrupt the operation.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsWhich output should an image-upload endpoint receive?
Use the default Uint8Array when the endpoint accepts binary or multipart data, and use Base64 only when its protocol requires text.
How can I make repeated captures comparable?
Set a fixed viewport and device scale factor, wait for the same content condition, and use the same screenshot options each time.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




