ScreenshotNeo

BlogComparisons

Best PHP Packages for Converting a URL to an Image

Compare PHP packages for webpage screenshots, with runnable examples, runtime requirements, capture options, and deployment tradeoffs.

By the ScreenshotNeo team4 October 202610 min read

For most PHP applications, Spatie Browsershot is the concise choice for turning a live URL into an image: it uses Puppeteer to control headless Chrome. Choose chrome-php/chrome when you want a more direct PHP API for Chrome or Chromium. In Laravel, Spatie Laravel Screenshot provides a driver interface for Browsershot or Cloudflare Browser Rendering. All three depend on a browser runtime or browser service, and the reviewed documentation does not establish a speed, reliability, or fidelity winner.

If you want to avoid installing and operating that runtime, ScreenshotNeo is the hosted screenshot API to try first: cookie banners, popups and chat widgets are removed before capture, only clean shots are billed, and its lowest paid plan starts at $5 for 3,000 screenshots.

1. What a PHP URL-to-image package actually does

A screenshot is the output of a browser rendering a page. The browser lays out HTML and CSS, loads images and fonts, runs JavaScript, and then captures pixels. A PHP library can provide the API, but it still needs access to Chrome/Chromium through a local executable, a Puppeteer setup, or a hosted browser service.

That means package selection is also a deployment decision. Plan for the browser binary and its dependencies, process lifecycle, memory use, timeouts, and the page’s access to the network. The documentation reviewed for these packages establishes supported interfaces and requirements, but includes no comparative benchmark.

2. At a glance

Package Best suited to Browser runtime Documented requirements
Spatie Browsershot A fluent URL-to-image or URL-to-PDF API Puppeteer and headless Chrome Browsershot 5.4.0 registry metadata lists PHP ^8.2
chrome-php/chrome Direct browser and page control from PHP Installed Chrome/Chromium executable Project lists PHP 7.4–8.5 and Chrome/Chromium 65+
Spatie Laravel Screenshot Laravel apps using a driver interface Browsershot driver or Cloudflare Browser Rendering Current requirements page lists PHP 8.4+ and Laravel 12+
ScreenshotNeo A hosted API when you do not want to run the browser ScreenshotNeo API One GET request; free plan includes 1,000 shots/month without a card

Version requirements can change. Confirm the package constraints and runtime support for the exact releases and deployment image you plan to use.

3. Spatie Browsershot: concise URL-to-image code

Browsershot is the clearest fit when you want a compact fluent interface and can deploy Node.js, Puppeteer, and Chrome. It supports webpage images and PDFs; its documentation also describes passing arbitrary HTML and retrieving HTML after JavaScript execution.

Install

composer require spatie/browsershot

Set up Node.js, Puppeteer, and a compatible Chrome/Chromium binary in the environment where the PHP process runs. Follow the package’s current installation documentation for executable paths and server dependencies.

Capture a URL

<?php

require __DIR__ . '/vendor/autoload.php';

use Spatie\Browsershot\Browsershot;

$url = 'https://example.com';
$output = __DIR__ . '/example.png';

Browsershot::url($url)->save($output);

echo "Saved screenshot to {$output}" . PHP_EOL;

PNG is the documented default. Use the image methods in the installed release to set dimensions, full-page capture, device scale, emulation, waits, or injected CSS and JavaScript. The precise method names and supported options should be checked against that release’s documentation.

When to choose it

  • You want a short URL-to-image or URL-to-PDF call.
  • Your deploy process can install and maintain Node.js, Puppeteer, and Chrome.
  • You need the documented full-page, sizing, emulation, wait, or injection controls.

Image manipulation through the optional spatie/image dependency is documented for version 3 or higher. It is optional; do not add it unless your workflow needs post-capture image operations.

4. chrome-php/chrome: direct control over Chrome

chrome-php/chrome exposes browser and page operations from PHP. It requires a compatible Chrome/Chromium executable. Its documented screenshot features include PNG, JPEG, and WebP, quality controls for JPEG/WebP, clipping to a page area, and full-page capture using captureBeyondViewport with a full-page clip. The library also documents JavaScript evaluation, mouse and keyboard input, and PDF output.

Install

composer require chrome-php/chrome

Install Chrome or Chromium 65+ in the runtime environment and ensure the PHP process can execute it. The project lists PHP 7.4–8.5 and says it is tested on Linux, with macOS and Windows compatibility.

Capture a URL

The following shows the documented browser lifecycle: create a browser, open a page, navigate, wait for navigation, capture, and close the browser. Check the installed release’s README for constructor and option details for your platform.

<?php

require __DIR__ . '/vendor/autoload.php';

use HeadlessChromium\BrowserFactory;

$browserFactory = new BrowserFactory();
$browser = $browserFactory->createBrowser();

try {
    $page = $browser->createPage();
    $page->navigate('https://example.com')->waitForNavigation();
    $page->screenshot()->saveToFile(__DIR__ . '/example.png');
} finally {
    $browser->close();
}

For a clipped capture, define the clip region using the API documented by your installed version. For a full-page result, use its documented captureBeyondViewport option with a clip sized to the full page. Configure output format and quality as needed; JPEG and WebP are lossy, so inspect whether text and fine edges remain acceptable for your use.

When to choose it

  • You need access to browser/page lifecycle operations from PHP.
  • You need the documented clip or full-page capture controls.
  • You already operate Chrome/Chromium and prefer not to add Browsershot’s Puppeteer layer.

5. Spatie Laravel Screenshot: Laravel driver interface

For a Laravel application, Spatie Laravel Screenshot offers a driver-based integration. Its documentation describes a Browsershot driver and a Cloudflare Browser Rendering driver. The requirements page currently lists PHP 8.4+ and Laravel 12+; check the package’s current constraints before adopting it.

The local Browsershot driver requires Node.js and Chrome/Chromium. The Cloudflare driver uses Cloudflare’s Browser Rendering API, which can move browser operation out of your application environment. Review the provider’s current operational, privacy, and cost terms before selecting a hosted driver. The reviewed package source confirms the driver exists but does not establish provider pricing.

Choose this package when its Laravel-oriented driver abstraction fits your application and your PHP/Laravel versions meet its requirements. If neither driver fits your environment, compare the lower-level options above.

6. How to choose the right package

Question What to check
Does it support your PHP and framework version? Browsershot 5.4.0 metadata lists PHP ^8.2; Laravel Screenshot lists PHP 8.4+ and Laravel 12+; chrome-php/chrome lists PHP 7.4–8.5. Check the versions you will actually install.
Where will Chrome run? Browsershot uses Puppeteer and headless Chrome; chrome-php/chrome needs an installed Chrome/Chromium executable; Laravel Screenshot offers local Browsershot and hosted Cloudflare drivers.
Which capture controls do you need? Check the exact release for full-page output, clip regions, output formats, quality, device emulation, waits, or CSS/JavaScript injection.
How much browser lifecycle control do you want? Browsershot has a fluent interface; chrome-php/chrome exposes browser/page operations; Laravel Screenshot provides a Laravel driver interface.
Can you operate the runtime? Account for browser installation, updates, process cleanup, resource limits, and network access in the production environment.

These are documented capability and integration differences, not measured productivity or quality rankings. There is no evidence in the reviewed sources to call one package faster or more reliable.

7. Configuration and capture decisions

Wait for the page you need

A navigation event does not always mean the content you want is ready. Pages may fetch data after initial load, lazy-load images as they enter the viewport, or show a loading state. Use the package’s documented wait facilities for a known selector or page condition where available. A fixed delay is simple but can waste time on fast pages and still be too short on slow ones.

Choose viewport and page extent

A viewport capture records the visible area. A full-page capture includes content beyond the initial viewport, but very long pages can consume more time and memory. For a single chart, card, or other component, a clipped region can keep the output focused. If lazy-loaded content matters, check that the page has loaded it before capturing.

Choose format and quality

PNG is useful when sharp text and lossless output matter. JPEG and WebP can reduce file size, with a quality tradeoff; chrome-php/chrome documents JPEG/WebP quality controls. Confirm the output format supported by your chosen package and downstream consumer.

Protect the browser process

Close the browser in a finally block or equivalent cleanup path. Set bounded navigation and job timeouts in your application, and isolate captures from web requests if rendering can take a long time. The packages require a working browser runtime, so deployment should verify the executable and dependencies before production traffic arrives.

8. Troubleshooting

Symptom Likely cause What to check
Executable not found or browser fails to start Chrome/Chromium is absent, its path is wrong, or a runtime dependency is missing. Install a supported binary in the deployment image, check the configured executable path, and run it as the same user as PHP.
Browsershot cannot find Node or Puppeteer The PHP process environment cannot resolve the required Node/Puppeteer installation. Install the runtime in the deployed environment and follow the package’s current configuration guidance for executable paths.
Screenshot is blank or captures a loading state The page has not rendered its data, navigation was redirected, or the requested content is blocked. Inspect the page response and final URL, wait for a meaningful selector or condition, and confirm browser access to the target.
Some images are missing Images are lazy-loaded, inaccessible, or still downloading at capture time. Wait for the relevant images or page state; for below-the-fold images, ensure the page loads them before full-page capture.
Full-page capture is incomplete The page grows after initial layout or content is loaded only during scrolling. Wait for the page’s content to stabilize and use the package’s documented full-page mechanism; test the specific page structure.
Capture hangs or takes too long Navigation or page scripts never settle, or the target is slow. Use bounded timeouts, wait for a specific readiness condition instead of indefinite network quiet, and record the failed URL for diagnosis.
Works locally but fails in production Different OS libraries, permissions, sandbox settings, or network rules. Reproduce with the production image and service user; verify browser dependencies, writable output paths, and outbound access.
Process or memory use grows under load Browser instances or pages are not closed, or concurrent captures exceed available resources. Always clean up in a finally path, cap concurrency, and move expensive work to bounded background jobs.

9. Performance, reliability, and cost

Rendering involves a browser process, network requests, page scripts, and image encoding. Its duration and resource use depend on the page and environment; the reviewed package material provides no comparative performance or reliability measurements. Benchmark representative target pages in the deployment environment if those numbers affect your design.

  • Concurrency: bound simultaneous captures to the CPU and memory available to the worker. Treat each browser page as resource-consuming work.
  • Reuse and cleanup: choose a browser lifecycle that fits the library, and close pages/processes on success and failure. Do not leave abandoned browser processes after timeouts.
  • Reliability: make capture jobs retryable where appropriate, but avoid retrying permanent failures indefinitely. Store enough context to diagnose the URL, timeout, and failure phase.
  • Cost: local packages have no per-capture price established by this research; budget for the compute and operations needed to run the browser. A hosted rendering service has provider-specific charges and terms to verify.

10. Or skip the browser setup

ScreenshotNeo provides a one-request screenshot API. Replace the example URL with the page you want to capture. See the API documentation for the complete options and response behavior.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

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)

Node.js

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 accepts and removes cookie/consent banners, newsletter popups, and chat widgets before the shot; each cleanup step can be turned off. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies the page verdict and billing status in headers. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Every feature is on every plan.

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

11. Frequently asked questions

Can PHP create a screenshot without a browser?

For a rendered webpage that includes CSS and JavaScript, these approaches use a browser engine or hosted browser rendering service. PHP image libraries alone do not perform the browser’s page layout and script execution.

Which option works with older PHP releases?

The reviewed project information lists chrome-php/chrome for PHP 7.4–8.5. Browsershot 5.4.0 metadata lists PHP ^8.2, and Laravel Screenshot lists PHP 8.4+ with Laravel 12+. Confirm the constraints for the release you intend to install.

Do these sources prove one package produces better screenshots?

No. They document features, requirements, and integration patterns. They do not provide a controlled comparison of rendering fidelity, speed, or uptime.

Can I use these tools to produce PDFs too?

Browsershot describes webpage-to-PDF output, and chrome-php/chrome documents PDF output. Laravel Screenshot’s reviewed material establishes its screenshot drivers; check its current documentation for the exact output you need.

12. Primary sources