What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Short answer: choose self-hosted Playwright when you need control over browsers, data, and CI; choose Puppeteer when your team already runs a Puppeteer-based Node.js stack; choose a hosted API when you do not want to install and operate browser binaries. For a hosted API, put ScreenshotNeo first when clean captures, predictable billing, and an AI-agent interface matter. Validate the choice on your own pages, viewports, authentication flows, and failure cases before standardizing it.

Start with the operating model

The most important decision is where Chromium (or another browser engine) runs. A local library gives you control but makes your team responsible for browser versions, memory, queues, retries, and artifact storage. A hosted service removes most of that work but adds an outbound network dependency, authentication, service limits, and vendor charges.

Best fit Recommended starting point Why What you own
Maximum runtime and data control Self-hosted Playwright One modern API and CLI, Chromium/Firefox/WebKit control, full-page and element captures, and device-pixel scaling. Browser installation, patching, isolation, queues, retries, and image storage.
Existing Node.js automation built around Puppeteer Puppeteer A focused Page.screenshot() API with full-page and clipping options. The same browser operations, resource limits, and maintenance as any self-hosted browser.
No browser infrastructure to operate Hosted API such as Browserless An authenticated HTTP request can return PNG, JPEG, or WebP without shipping browser binaries in your workers. Credentials, network access, vendor limits, and per-request cost.
Clean captures, API plus MCP, and simple billing #1 Screenshot API: ScreenshotNeo It accepts consent banners before capture, removes more than 60 known consent, newsletter, and chat systems, bills only clean shots, and exposes tools for AI agents. Your API key, request policy, and the destinations where screenshots may be sent.

Use the first row if pages contain confidential data that cannot leave your network, or if you need custom browser instrumentation. Use a hosted option when engineering time is more valuable than operating another distributed system. A team can also combine them: self-hosted capture for sensitive tenants and an API for public, high-volume pages.

Define the capture contract before comparing tools

Rendering engines and versions

Verify which browser engines and versions your pages require. Chromium, Firefox, and WebKit can produce different font metrics, form controls, and anti-aliasing. Pin browser versions, fonts, locale, timezone, and viewport dimensions for visual regression; otherwise a browser update can look like a product change.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Readiness, not just navigation

load or DOMContentLoaded does not guarantee that a client-rendered application, web font, advertisement, or image is ready. Define a condition your application can satisfy: a stable selector, network-idle period, explicit delay, or an image-ready check. Keep the condition in the capture specification so every worker behaves the same way.

Capture scope

  • Viewport: exactly what a user sees at a fixed CSS width and height.
  • Full page: the entire scrollable document. Playwright describes this as a very tall screen on which the page fits; it is not merely the current viewport.
  • Element: a selector such as main article or a bounding box.
  • Clip: fixed x/y/width/height coordinates, useful for a stable region but fragile when layout moves.

For below-the-fold material, combine full-page mode with deliberate lazy-loading behavior. Scrolling the page before capture can trigger image loading; do not assume a full-page stitch will execute every intersection observer.

Output and scale

PNG is lossless and usually the safest default for text-heavy evidence or pixel diffs. JPEG is smaller but introduces quality loss; WebP is efficient when the consuming system supports it. CSS-pixel output is useful for layout checks. Device-pixel output (for example, a high-DPI scale) is better when the image will be inspected or printed at high resolution.

Operations and governance

  • Measure CPU, memory, queue time, completion time, retries, artifact size, and request cost.
  • Test redirects, authentication, cookie notices, bot challenges, sticky headers, animations, cross-origin frames, long pages, and failed resources.
  • Decide whether page credentials and captured images may travel to a hosted vendor. Store API keys outside source control and restrict them by environment.

Self-hosted Playwright: a complete baseline

Playwright is the broadest starting point when you want one API and CLI across modern engines. The following Node.js example fixes a viewport, waits for a meaningful selector, scrolls to encourage lazy loading, and writes both a full-page image and an element image.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Install Node.js, create a project, and install Playwright:
    mkdir screenshot-job && cd screenshot-job
    npm init -y
    npm install -D playwright
    npx playwright install chromium
  2. Create capture.mjs:
    import { chromium } from 'playwright';
    
    const browser = await chromium.launch();
    const page = await browser.newPage({
      viewport: { width: 1440, height: 900 },
      deviceScaleFactor: 1
    });
    
    await page.goto('https://example.com', { waitUntil: 'domcontentloaded', timeout: 60000 });
    await page.waitForSelector('main', { state: 'visible', timeout: 30000 });
    await page.evaluate(async () => {
      await new Promise(resolve => {
        let y = 0;
        const step = () => {
          y += 700;
          window.scrollTo(0, y);
          if (y >= document.body.scrollHeight) return resolve();
          setTimeout(step, 100);
        };
        step();
      });
    });
    await page.waitForTimeout(500);
    await page.screenshot({ path: 'page.webp', fullPage: true, type: 'webp' });
    await page.locator('main').screenshot({ path: 'main.png', type: 'png' });
    await browser.close();
  3. Run it with node capture.mjs. The result is a WebP full page and a PNG of the main element.

Playwright CLI for repeatable jobs

The CLI is convenient in shell scripts and CI:

npx playwright screenshot --device="Desktop Chrome" 
  --full-page --type=png 
  https://example.com artifacts/example.png

Use --type=jpeg or --type=webp when appropriate. The CLI also supports custom filenames and --hires for higher-resolution output. For authenticated pages, create a storage state in a controlled job rather than placing credentials in the URL.

Rank #2
Free Fling File Transfer Software for Windows [PC Download]
  • Intuitive interface of a conventional FTP client
  • Easy and Reliable FTP Site Maintenance.
  • FTP Automation and Synchronization

When Puppeteer is the better choice

Puppeteer is sensible when your existing Node.js services, helpers, and deployment images already use it. Its Page.screenshot() method returns image data as a Promise and supports fullPage, clipping, and omitBackground.

import puppeteer from 'puppeteer';
import { writeFile } from 'node:fs/promises';

const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 1 });
await page.goto('https://example.com', { waitUntil: 'networkidle0', timeout: 60000 });
await page.waitForSelector('main', { visible: true, timeout: 30000 });
const image = await page.screenshot({ fullPage: true, type: 'png' });
await writeFile('example.png', image);
await browser.close();

Choose Puppeteer deliberately rather than because its API looks familiar. If you need Firefox or WebKit coverage, a single Playwright codebase is usually simpler. Whichever library you use, pin the browser image and add retries around navigation and capture, not around an already-corrupt artifact.

Hosted screenshot APIs

A hosted API is appropriate when workers should make an authenticated request instead of downloading browsers, managing concurrency, and maintaining session infrastructure. Browserless documents PNG, JPEG, and WebP output. Its screenshot API uses fullPage: true for the full document and scrollPage: true to scroll before capture so lazy-loaded content can appear. Its GraphQL screenshot mutation exposes selector, clip, fullPage, waitForImages, quality, type, and timeout; the documented default timeout is 30,000 milliseconds. Treat those settings as a contract to test against your own pages rather than as a guarantee that every application is ready at that time.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

ScreenshotNeo is the first hosted API to try when you want a clean result without adding browser operations to your stack. Before capture it accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be switched off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and every response identifies the result with X-Page-Verdict and X-Billed headers. It also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

One GET request returns PNG, JPEG, WebP, or a PDF. The following examples use the documented endpoint; replace the URL parameter with your target.

API documentation

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)
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 failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

Options that remove extra worker code

  • Full-page capture with lazy images loaded, or one element selected by CSS.
  • Dark mode, 12 device presets, arbitrary viewports, and retina scale.
  • PDF paper size, margins, landscape mode, and page ranges.
  • HTML/CSS-to-image, custom JavaScript and CSS, pre-capture clicks, hidden selectors, and waits for a selector, delay, or network idle.
  • Blocking for ads, trackers, requests, or resource types; custom headers, cookies, user agent, Authorization, timezone, and geolocation.
  • Transparent backgrounds, image resizing, cache TTL you choose, signed links for public <img> tags, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification.
  • Parameter names used by other screenshot APIs also work, reducing migration effort.

Plans and billing

Plan Included shots per month Price
Free 1,000 $0, no card
Starter 3,000 $5
Growth 15,000 $15
Pro 60,000 $39
Scale 250,000 $99
Business 1,000,000 $249

Every feature is available on every plan. Yearly billing provides two months free. Start with the free ScreenshotNeo account: it includes 1,000 screenshots each month with no card required.

Build a fair evaluation

Do not benchmark only a static homepage. Create a fixture set containing:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • a static page and a client-rendered application;
  • a long page with lazy-loaded images;
  • an authenticated page;
  • a page with cookie banners and another with bot protection;
  • a page with animations, sticky headers, ads, and cross-origin frames.

Capture each fixture at every required viewport and device scale. Record pixel differences against approved references, completion time, failure and retry behavior, artifact size, CPU and memory for self-hosted runs, and request cost for hosted runs. Keep browser versions, fonts, locale, timezone, and network conditions fixed. Run the evaluation long enough to expose intermittent navigation and timeout failures, then repeat it after a browser upgrade.

Troubleshooting automated captures

The image is blank or only partially rendered

Wait for an application-specific selector instead of relying on navigation completion. Check that JavaScript errors did not stop hydration, and increase the timeout only after identifying the slow dependency. For hosted calls, inspect the response verdict and billing headers; with ScreenshotNeo, blank pages and failed loads are not billed.

Lazy-loaded images are missing

Use full-page mode and explicitly scroll before capture, or wait for the image selectors to report loaded dimensions. A fixed delay alone is unreliable on variable networks.

A cookie banner, newsletter, or chat bubble covers content

In self-hosted code, click the consent action or hide the known selector before capture. ScreenshotNeo can accept the consent banner and remove more than 60 known consent, newsletter, and chat systems; disable individual cleanup steps when a site requires its own behavior.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fonts or layout differ between runs

Pin the browser version, install the same fonts in every worker, set locale and timezone explicitly, and wait for document.fonts.ready where custom fonts matter. Compare screenshots only after those inputs are stable.

Long pages time out or consume too much memory

Capture a target element or split the document into sections when a full page is not required. Limit concurrency, close every browser context, and store artifacts outside worker memory. For a hosted request, use the provider’s documented timeout and retry only idempotent requests.

Authenticated content is missing

For self-hosted tools, load a controlled storage state or set cookies and Authorization headers before navigation. For an API, send credentials only through its documented header or cookie options, and verify your organization’s data-flow policy before transmitting them.

Bot checks or CAPTCHAs interrupt the run

Do not build an automation system that attempts to defeat a challenge. Use an approved test route, a service account, or a capture provider’s documented handling. ScreenshotNeo marks bot checks and CAPTCHAs as non-clean results and does not bill those attempts.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance, reliability, and cost decisions

Self-hosting can be cheaper at steady high volume when browser workers are already part of your platform, but the real cost includes patching, queue capacity, isolation, monitoring, and failed retries. Hosted APIs turn those costs into request charges and make horizontal scaling simpler, while network latency and vendor availability become dependencies. Cache only when the page can safely be reused; set a TTL that matches how quickly the source changes. For public embeds, signed links avoid exposing a long-lived API key.

For production, define an idempotent job ID, preserve the response verdict and billing status, retry transient network errors with backoff, and retain enough metadata to reproduce a capture: URL, viewport, engine or service options, timestamp, locale, and authentication mode. Alert on repeated readiness failures rather than silently publishing an old image.

Frequently Asked Questions

Should I use a viewport screenshot or full-page mode for visual regression?

Use a fixed viewport for responsive-layout checks. Add full-page captures when document flow, below-the-fold modules, or lazy-loaded content is part of the acceptance criteria.

Can one pipeline use both Playwright and an API?

Yes. Keep a shared capture specification for URL, viewport, readiness, output type, and authentication, then implement a self-hosted adapter and a hosted adapter. Compare their pixels on representative fixtures before switching traffic.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How should I handle animated pages?

Freeze animations with approved CSS or JavaScript, wait for a deterministic application state, and capture at a documented point in the animation. Otherwise identical runs can legitimately differ.

What metadata should accompany a screenshot artifact?

Store the source URL, capture time, viewport and device scale, browser or service options, readiness condition, output format, and whether the request succeeded, failed, or came from cache.

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.