ScreenshotNeo

BlogComparisons

What to Use Instead of PhantomJS for Website Screenshots

PhantomJS development is suspended. Compare Puppeteer and Playwright for screenshot work, then migrate with runnable examples and a checklist.

By the ScreenshotNeo team4 October 20267 min read

Short answer: For website screenshots, evaluate Puppeteer first if your project is already JavaScript and a Chromium based automation stack fits. Evaluate Playwright when full page or element capture and screenshot based visual comparisons matter most. PhantomJS itself says development is suspended, so plan a migration rather than building new screenshot work around it. Neither library is a universal winner: choose based on capture scope, output requirements, and how consistently you can reproduce the browser environment.

PhantomJS was a JavaScript scriptable headless browser built on QtWebKit. Its documented uses included page automation, screenshots, headless website testing, and network monitoring. A screenshot replacement may not cover all of those jobs, so first identify what your existing scripts actually do.

1. Choose a replacement by the screenshot job

Need Start with Why
Page screenshots in an existing JavaScript and Chromium workflow Puppeteer Its official guide documents page capture with Page.screenshot() and element capture with ElementHandle.screenshot().
Full page or element screenshots and visual regression comparisons Playwright It documents viewport, full page, and element captures, as well as screenshot comparison through Playwright Test.
One off or service based captures without managing a browser runtime ScreenshotNeo It returns screenshots or PDFs from a GET request; cookie banners, popups, and chat widgets are handled before capture, and only clean shots are billed.

These are workflow based starting points, not benchmark rankings. The reviewed official documentation does not establish a universal speed, fidelity, cost, or compatibility winner. See the Puppeteer screenshot guide, Playwright screenshot documentation, and Playwright visual comparison documentation.

2. Inventory the PhantomJS behavior you depend on

Before porting code, write down each script’s job and output. PhantomJS’s capture guide documented PNG, JPEG, GIF, and PDF, plus viewport and clipping controls. Verify that the replacement and surrounding code support the particular format and capture behavior you need; do not assume APIs map one to one.

  1. Classify each job: viewport image, full page image, element image, PDF, visual test, general browser automation, or network monitoring.
  2. Record output format, viewport dimensions, clipping rectangle, page readiness behavior, and any scroll or interaction steps.
  3. Note whether the script uses PhantomJS features beyond screenshots. A screenshot API will not necessarily replace testing, network monitoring, or general automation.
  4. Choose representative pages, including dynamic pages, long pages, and pages where the target element appears after interaction.
  5. For visual baselines, pin the browser/runtime and execution environment, then regenerate and review the reference images intentionally.

3. Puppeteer: capture a page or element

Puppeteer is a practical first candidate for a JavaScript project that wants browser driven screenshots. Install it using the project’s package manager and follow the current official installation guide for the supported runtime and browser setup.

npm install puppeteer

Save this as screenshot.mjs, then run node screenshot.mjs https://example.com. It captures the page after a network idle wait and writes a PNG. The URL argument must be a page you are authorized to access.

import puppeteer from 'puppeteer';

const url = process.argv[2] ?? 'https://example.com';
const browser = await puppeteer.launch({ headless: true });
try {
  const page = await browser.newPage({
    viewport: { width: 1440, height: 1000 },
    deviceScaleFactor: 1,
  });
  await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });
  await page.screenshot({ path: 'page.png', fullPage: true });
} finally {
  await browser.close();
}

To capture one element instead, use a locator and its screenshot method:

const target = page.locator('main article');
await target.waitFor({ state: 'visible', timeout: 15000 });
await target.screenshot({ path: 'article.png' });

Network idle is not a universal readiness condition. Pages with polling, streaming, analytics, or long lived connections may never become idle. For those pages, wait for a meaningful selector or a bounded delay instead. Puppeteer’s guide shows the core page and element capture APIs; consult its current API documentation for options such as image type, quality, clipping, and full page capture.

4. Playwright: capture pages, full pages, and elements

Playwright’s screenshot API supports standard viewport, full page, and locator based element captures. Install the library and browser binaries following the official setup guide.

npm init -y
npm install playwright
npx playwright install chromium

Save as capture.mjs and run node capture.mjs https://example.com:

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: 1000 } });
  await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 });
  await page.locator('main').waitFor({ state: 'visible', timeout: 15000 });
  await page.screenshot({ path: 'page.png', fullPage: true });
  await page.locator('main').screenshot({ path: 'main.png' });
} finally {
  await browser.close();
}

Playwright also supports image format, quality, clipping, and screenshot testing options. Check the screenshot guide for the options and constraints that apply to your installed version. For visual regression, use a controlled environment and Playwright’s snapshot comparison workflow.

5. Map PhantomJS requirements to the new workflow

Requirement to migrate What to decide
Image format Confirm PNG, JPEG, or another required format is supported by your selected capture path; validate file extension and encoding.
Viewport and clipping Set viewport dimensions explicitly. Translate old viewport or clip rectangle behavior and inspect edge pixels and scroll boundaries.
Full page Use the library’s full page option, then check pages with lazy images, sticky headers, or very large content.
Element screenshot Wait for the target selector to exist and be visible before capturing. Handle absent or duplicate matches deliberately.
Readiness Choose navigation completion, a selector, a specific application state, or a bounded delay. Do not blindly retain one wait rule for every site.
PDF or non-screenshot jobs Confirm the new tool covers those jobs, or keep them as a separate migration workstream. Screenshot support alone does not replace PhantomJS automation or monitoring.
Visual comparison Keep OS, browser version, browser settings, hardware, power conditions, and headless mode consistent where practical.

6. Reliability, performance, and cost considerations

Reliability

A screenshot is only as repeatable as the page state and browser environment. Wait for an application specific signal where possible, use fixed viewport and device scale settings, and make authentication and test data deterministic. Playwright warns that rendered output can vary with host OS, browser version, settings, hardware, power source, and headless mode. Keep those conditions aligned with the environment that generated visual baselines.

Performance

The research sources do not provide comparative benchmark results, so do not choose based on unsupported speed claims. Measure your own representative URLs, including cold starts and dynamic pages. Reuse a browser process for a batch where the library’s lifecycle and your isolation requirements permit it; always close pages and browser processes on success and failure. Set timeouts so a stalled page cannot occupy a worker indefinitely.

Cost

Self hosting shifts cost into browser installation, compute, maintenance, and engineering time; no total cost comparison is established by the reviewed library documentation. ScreenshotNeo’s stated plans are Free: 1,000 shots/month with no card; Starter: $5 for 3,000; Growth: $15 for 15,000; Pro: $39 for 60,000; Scale: $99 for 250,000; Business: $249 for 1,000,000. Yearly billing gives two months free, and every feature is on every plan. Check ScreenshotNeo for current product details.

7. Troubleshooting migration problems

Symptom Likely cause Fix
Navigation times out The page keeps network connections open or does not reach the chosen idle condition. Use a less strict navigation milestone, then wait for a specific visible selector or application state. Keep a finite timeout.
Screenshot is blank or incomplete Capture started before the relevant content rendered, or the page requires an interaction. Wait for a selector tied to the content, perform required clicks, and check the page state before capture.
Images are missing on long pages Images may load lazily as the page is scrolled. Use full page capture support and verify lazy content behavior. If needed, scroll through the page before capturing and wait for images to finish loading.
Element capture fails The selector does not match, is hidden, or appears too late. Check selector uniqueness and visibility; add an explicit wait and handle an absent target as an expected error.
Visual diffs appear across machines Different OS, browser version, settings, hardware, or headless mode can change rendered output. Pin and standardize the screenshot environment and regenerate baselines only after reviewing the change.
Migration misses a former PhantomJS task The old script also did automation, testing, or network monitoring. Inventory that behavior separately and verify a replacement for each responsibility; screenshot APIs alone may not cover it.

8. Or skip the browser setup

For a screenshot without installing or operating a browser runtime, ScreenshotNeo accepts a URL and returns an image or PDF. This example saves a WebP response for Stripe; replace the target URL with the page you need to capture. See the ScreenshotNeo API documentation for request options and response details.

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}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(async fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));

Cookie banners are accepted or removed before capture, including 60+ known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify page verdict and billing status. An MCP server gives AI agents tools for screenshots, page information, and PDF capture. The free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000.

Sign up free for ScreenshotNeo: 1,000 screenshots a month, no card required.

9. Frequently asked questions

Is PhantomJS still maintained?

Its homepage states that development is suspended until further notice.

Can Puppeteer or Playwright replace every PhantomJS use?

Not automatically. They provide screenshot workflows, but your old scripts may also perform automation, testing, or network monitoring. Check each responsibility during migration.

Which is better for visual regression?

Playwright has documented screenshot comparison support. Whichever workflow you choose, keep the browser and host environment consistent because rendering can vary.

Should I expect pixel identical output after switching?

No. Changing browser engines, browser versions, fonts, rendering settings, and host environments can alter pixels. Capture new references in a controlled environment and review the differences.