ScreenshotNeo

BlogComparisons

PhantomJS vs Playwright for Website Screenshot Automation

Compare PhantomJS and Playwright for website screenshots, with runnable examples, migration guidance, visual testing advice, and a hosted API alternative.

By the ScreenshotNeo team4 October 20268 min read

For new website screenshot automation, choose Playwright. It documents support for Chromium, Firefox, and WebKit, offers page screenshot APIs, and includes screenshot comparison in Playwright Test. PhantomJS can still capture screenshots, but its project says development is suspended, so it is best treated as a legacy option. This recommendation is based on project documentation, not a head-to-head benchmark.

Use PhantomJS when you need to keep an existing script working while planning a migration. Use Playwright when building new automation, targeting current browser engines, or maintaining visual screenshot baselines.

Quick comparison

Area PhantomJS Playwright What it means
Project status Development is suspended. Current browser and API documentation is published. Playwright is the practical choice for new work; plan a migration from PhantomJS.
Browser engines QtWebKit backend. Chromium, Firefox, and WebKit projects. Playwright has broader documented engine coverage.
Capture Page rendering, viewport size, clip rectangle, PNG, JPEG, GIF, and PDF are documented. Page screenshot API with configurable options. Both can capture; engine currency and workflow matter for new systems.
Visual comparison The reviewed capture guide documents rendering, not a current first-party visual comparison workflow. Playwright Test can create reference screenshots and compare later runs. Use Playwright when screenshot assertions are part of the test suite.
Reproducibility No current reproducibility guarantee was established in the reviewed documentation. Documentation warns that rendering varies with OS, browser version, settings, hardware, power source, and headless mode. Pin and control the environment for meaningful comparisons.

Sources: PhantomJS project homepage, PhantomJS screen capture guide, Playwright browser documentation, Playwright Page screenshot API, and Playwright visual comparisons.

What each tool does

PhantomJS

PhantomJS is a headless browser built on QtWebKit. Its capture guide shows opening a page and rendering it to an image, setting viewport dimensions, and clipping a capture rectangle. It documents PNG, JPEG, GIF, and PDF output, and describes capturing HTML/CSS, SVG, images, and Canvas. It is not accurate to say PhantomJS cannot take screenshots. The central drawback for a new project is that its development is suspended.

Playwright

Playwright automates Chromium, Firefox, and WebKit. Its Page API captures screenshots, while Playwright Test adds toHaveScreenshot() to generate a reference image and compare later runs. The browser documentation also covers installing browser binaries and using branded Chrome and Edge channels.

Screenshot capture and screenshot regression testing are related but different jobs. A capture saves what the browser rendered. A visual test compares that output against a reviewed baseline and reports differences.

Capture a page with Playwright

The following JavaScript example is a complete runnable capture script. Install Playwright, install its Chromium browser, save the script, then run it. It waits for the page load event, captures the full page, and writes a PNG.

npm init -y
npm install playwright
npx playwright install chromium
// screenshot.mjs
import { chromium } from 'playwright';

const url = process.argv[2] ?? 'https://example.com';
const browser = await chromium.launch({ headless: true });
try {
  const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
  const response = await page.goto(url, { waitUntil: 'load', timeout: 30_000 });
  if (!response || !response.ok()) {
    throw new Error(`Navigation failed: ${response?.status() ?? 'no response'}`);
  }
  await page.screenshot({ path: 'page.png', fullPage: true });
} finally {
  await browser.close();
}
node screenshot.mjs https://example.com

The screenshot API accepts options such as output path, full-page capture, clip rectangle, image type, quality for JPEG, and transparency for PNG. For a fixed viewport capture, omit fullPage. For a specific region, pass a clip rectangle with coordinates and dimensions. Consult the Page screenshot API for the current option list and constraints.

Capture with Playwright Test and compare a baseline

For regression testing, add Playwright Test and define an explicit browser project. The first run creates a reference screenshot; subsequent runs compare against it. Review baseline changes deliberately rather than accepting every updated image automatically.

npm install --save-dev @playwright/test
npx playwright install chromium
// playwright.config.js
import { defineConfig } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  projects: [
    { name: 'chromium', use: { browserName: 'chromium' } },
  ],
});
// tests/home.spec.js
import { test, expect } from '@playwright/test';

test('home page visual baseline', async ({ page }) => {
  await page.goto('https://example.com');
  await expect(page).toHaveScreenshot('home.png', { fullPage: true });
});
npx playwright test

Use the snapshot update option documented by Playwright when you have inspected and accepted an intentional visual change. For cross-browser coverage, configure Chromium, Firefox, and WebKit projects and install the corresponding browser binaries through the Playwright CLI. Branded Chrome and Edge channels are also documented options.

Keep visual comparisons reproducible

Playwright cautions that rendering can vary by host operating system, browser version, settings, hardware, power source, and headless mode. A screenshot mismatch does not automatically mean the site changed. For stable results:

  • Run baseline creation and comparison in the same OS image and browser version.
  • Keep viewport dimensions, device scale, fonts, locale, timezone, and browser settings fixed.
  • Use stable test data and avoid capturing while animations or asynchronous content are changing.
  • Wait for a meaningful page condition, such as a visible heading or loaded application state, rather than relying on an arbitrary short delay.
  • Mask or hide volatile content when appropriate; Playwright visual comparison guidance supports filtering volatile elements with a custom stylesheet.
  • Inspect the generated diff and approve changed baselines as code changes.

These steps reduce noise; they do not make every visual test perfectly deterministic. Pinning browser versions also means updating them intentionally and reviewing baseline changes after an update.

Migration guidance for PhantomJS scripts

  1. Inventory the current behavior. Record URLs, viewport and clipping rules, output formats, scripts, timing assumptions, headers, cookies, and how failures are handled.
  2. Separate capture from assertions. Identify whether the script only saves images or whether a separate process compares them. Choose Playwright Test if visual baselines are part of the desired workflow.
  3. Port a representative page first. Recreate viewport, full-page or clip capture, and any required authentication or navigation steps. Compare outputs for expected content, not pixel identity across different engines.
  4. Choose browser coverage. Start with the engine your users or tests require. Add Firefox and WebKit projects where cross-engine behavior matters.
  5. Stabilize the execution environment. Pin the CI image and Playwright dependency, install matching browser binaries, and run baseline updates in that environment.
  6. Run old and new paths during transition. Keep the legacy capture available until the Playwright result covers required pages and error handling, then retire it according to your release process.

Do not assume screenshots will match pixel-for-pixel after changing browser engine, fonts, operating system, or rendering settings. Establish new reviewed baselines under the Playwright environment.

Or skip the browser setup

If you need screenshots from an API rather than a browser automation runtime, ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. A GET request returns PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API documentation for request options and setup.

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 request failed: ${res.status}`);
await Bun.write('shot.webp', res);

ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, with response headers indicating the page verdict and billing status. Its MCP server gives AI agents tools for screenshots, page information, and PDF capture. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Every feature is available on every plan.

Create a free ScreenshotNeo account for 1,000 screenshots a month with no card.

Performance, reliability, and cost

Performance

No head-to-head timing benchmark is established by the cited documentation, so there is no sound basis here to claim one tool is faster. With either approach, page load behavior, scripts, image loading, and the target site affect completion time. In Playwright, choose navigation and readiness conditions that fit the page: waiting for full network inactivity can be problematic for sites with persistent connections, while a specific selector can represent the state you actually need.

Reliability

Playwright’s documented engine support and maintained browser installation workflow suit ongoing automation, but browser updates and environment changes still need maintenance. Visual tests can produce noisy diffs when the environment or dynamic content changes. PhantomJS remains capable of capture, but suspended development makes it a less suitable foundation for new long-lived automation.

Cost

Both browser automation approaches require operating and maintaining the environment that runs them; actual infrastructure cost depends on workload and deployment choices. A hosted API trades browser installation and runtime management for per-plan usage. ScreenshotNeo pricing is Free for 1,000 shots/month, Starter $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000. Yearly billing gives two months free. These are plan allowances, not a benchmark comparison.

Troubleshooting

Symptom Likely cause Fix
Playwright says the browser executable is missing. The matching browser binary was not installed in the environment. Run npx playwright install chromium or install the engines required by configured projects; ensure CI installs browsers for the same Playwright version.
Navigation times out. The site is slow, blocks automation, or never reaches the selected load condition. Check the URL and response first; raise the timeout only when justified, and wait for a specific page state where possible.
Screenshot is blank or incomplete. The page was captured before application content or lazy-loaded content appeared. Wait for a meaningful selector or application-ready condition, then capture. Scroll or otherwise trigger lazy content when the test requires it.
Visual test fails on CI but passes locally. OS, fonts, browser version, headless mode, settings, or hardware differ. Use the same pinned environment for baseline and comparison; avoid updating snapshots until the diff is understood.
Diffs change between runs. Animations, timestamps, rotating content, ads, or asynchronous data are volatile. Control test data, wait for stable state, and mask or hide known volatile regions using documented screenshot comparison controls.
PhantomJS renders a page differently from a current browser. Its QtWebKit rendering stack is not the same engine/version as the target browser. Treat the output as a legacy rendering result; migrate and establish baselines under the engine the project needs.
PhantomJS maintenance becomes a blocker. The project homepage says development is suspended. Keep the existing workflow only as a transition measure and plan a Playwright migration for ongoing work.

FAQ

Can PhantomJS still take screenshots?

Yes. Its official capture guide documents screenshots and PDF output. Its project homepage says development is suspended.

Is Playwright better for screenshot testing?

For a new maintained workflow, it is the stronger documented choice because Playwright Test supports reference screenshots and later comparisons. Reliable results still depend on a controlled environment.

Does Playwright make screenshots identical across browsers?

No. Chromium, Firefox, and WebKit can render differently, and the host environment can also affect output. Treat each browser and environment as a distinct baseline where needed.

Should I migrate every PhantomJS script immediately?

Not necessarily. Keep a working legacy script while you inventory its requirements and validate a representative Playwright replacement. The suspended project status makes migration planning prudent for new maintenance needs.

When should I use a screenshot API instead?

Use one when you want a simple HTTP call or an agent-accessible screenshot tool without installing and operating browser binaries in your own runtime. For local browser control and test assertions, Playwright remains the direct fit.