Compare PHP Browsershot and Symfony Panther for Website Screenshots
Choose Browsershot to render a URL or HTML; choose Panther when screenshots belong to a browser-driven test or user journey. Compare setup, code, CI, and trade-offs.
Short answer: Choose Browsershot when the job is to render a URL, HTML string, or local HTML file into an image or PDF. Choose Symfony Panther when the screenshot is part of a browser-driven workflow: navigate, wait for application state, interact with the page, then capture what the browser displays.
Both can produce website screenshots from PHP, but they solve different problems. Browsershot provides a rendering-oriented interface built around Node.js and Puppeteer. Panther controls Chrome/Chromium or Firefox through WebDriver and fits naturally into end-to-end tests. The choice below is based on their documented purposes and APIs; the sources reviewed do not establish a head-to-head speed benchmark.
1. The practical difference
| Question | Browsershot | Symfony Panther |
|---|---|---|
| What is the main operation? | Give it a URL or HTML input and save a rendered image or PDF. It can also return rendered HTML and report requests triggered by the page. | Drive a real browser through navigation and interaction, then capture a screenshot at the required state. |
| How is the browser controlled? | The current repository setup refers to Node.js and Puppeteer. | WebDriver controls Chrome/Chromium or Firefox; the browser client exposes navigation, clicks, waits, and screenshots. |
| What happens before capture? | Typically, specify the page or markup to render and any rendering options needed by the task. | Write the browser journey: load a page, wait for an element or visibility, interact if needed, and take the screenshot. |
| Where does it fit? | Image/PDF generation, page previews, or rendered markup capture. | End-to-end tests, crawling, and screenshots that need JavaScript-driven application state or user actions. |
| What setup must be managed? | PHP package plus Node, Puppeteer, and the browser setup required by the installed version. | PHP and compatible Symfony components, a supported browser, and a matching WebDriver installation. |
Symfony describes Panther as a way to run end-to-end tests in a real browser, headlessly in CI or with a GUI for debugging. Its documentation demonstrates JavaScript execution, screenshot capture, and waiting for page state. Browsershot’s repository documents rendering URLs and supplied HTML to output, as well as retrieving body HTML after JavaScript has run. Symfony’s end-to-end testing guide and the Browsershot repository are the primary references for those capabilities.
2. Use Browsershot for direct rendering
Browsershot is a good fit when you already know what to render and do not need to express a user journey in the browser. The repository documents URL input, raw HTML, and a local HTML file. This minimal example renders a URL and writes a PNG:
<?php
require __DIR__ . '/vendor/autoload.php';
use Spatie\Browsershot\Browsershot;
Browsershot::url('https://example.com')
->save('page.png');
Install the PHP package using Composer, then follow the current repository instructions for the Node.js, Puppeteer, and browser requirements for your chosen version. The current instructions refer to Node and Puppeteer. The repository mentions an older v2 based on Chrome’s headless CLI and identifies it as unmaintained, so do not select it as a shortcut without checking its maintenance status and compatibility.
Render supplied HTML or a local file
If the page is generated by your application, pass the markup directly. For a local HTML file, use the file input documented by the package. Keep external assets reachable from the rendering environment; a local file’s relative URLs may resolve differently than they do in your development browser.
<?php
require __DIR__ . '/vendor/autoload.php';
use Spatie\Browsershot\Browsershot;
$html = '<!doctype html><html><body><h1>Invoice preview</h1></body></html>';
Browsershot::html($html)->save('markup.png');
Browsershot::htmlFromFile(__DIR__ . '/preview.html')->save('file.png');
These examples show the input forms documented by Browsershot. For exact method names and supported options in the version you install, check that version’s repository documentation before copying options from another release.
When the rendered result matters more than the source
The repository also documents retrieving the page body after JavaScript execution and collecting requests triggered by the page. This can help when you need rendered output or want to inspect what the page requested, while keeping the overall task rendering-oriented. If you need to click through a workflow or wait for a particular visible application state, Panther’s browser-client model is usually a clearer fit.
3. Use Panther for browser journeys and test screenshots
Panther’s client lets PHP code control a browser. A basic page capture can be written as follows. This example assumes Panther, a compatible browser, and its matching WebDriver are installed and available in the environment.
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Panther\PantherTestCase;
$client = PantherTestCase::createPantherClient();
$client->request('GET', 'https://example.com');
$client->takeScreenshot(__DIR__ . '/page.png');
In a Panther end-to-end test, use the test case and client setup appropriate to your project. Symfony’s guide shows Panther integration with PHPUnit and the PantherTestCase pattern. It also documents using Chrome or Firefox clients and taking a screenshot from the client.
Wait for the page state you intend to capture
A screenshot immediately after navigation can miss content that loads asynchronously. Panther documents waiting for a DOM element or waiting for it to become visible. In a test, anchor capture to a meaningful state, such as the report heading or a ready indicator, rather than relying only on a fixed delay.
// Within a Panther test after requesting the page:
$client->waitFor('main h1');
$client->takeScreenshot(__DIR__ . '/ready-page.png');
Use the wait form that matches the condition your application exposes, and check the current Symfony guide for the exact API in your installed version. A visible element is a stronger signal than navigation completion when the screenshot depends on client-side rendering.
Use Panther screenshots to diagnose failing tests
Symfony recommends registering the Panther PHPUnit extension for testing. The extension can improve performance and enables interactive debugging. Symfony also documents the PANTHER_ERROR_SCREENSHOT_DIR environment variable for automatically saving screenshots after client creation when tests fail. Treat those failure artifacts as diagnostic evidence: your test should still define the page state it intends to verify and capture.
4. Setup and CI considerations
Browsershot
- Install the PHP package and the Node.js/Puppeteer/browser components required by the current Browsershot version.
- Ensure the process that runs PHP can find and execute the configured Node and browser tools.
- In CI or containers, make the runtime dependencies explicit in the build image so local and automated runs use the same setup.
- Verify that the page’s fonts, images, stylesheets, and other assets can be loaded from that environment.
Panther
- Install Panther and check PHP and Symfony component constraints against your project’s locked dependencies.
- Provide a supported Chrome/Chromium or Firefox browser plus its compatible WebDriver. Symfony documents installer, manual-download, and operating-system package-manager routes.
- In CI, install and pin a compatible browser/driver pair as part of environment setup; diagnose mismatches before debugging application selectors.
- Symfony’s container guidance discusses disabling Chrome’s sandbox in some environments and labels that option unsafe. Do not copy sandbox flags without reviewing the security requirements of the environment.
Version constraints change. At the time covered by the supplied research, Packagist listed Panther 2.4.0, published on 2026-01-08, with PHP >=8.1 and Symfony component constraints including ^6.4, ^7.3, and ^8.0 for several components. Check Packagist and your lock file before selecting a version.
5. Decision checklist
- Choose Browsershot if your input is a URL, HTML string, or local HTML file and your output is an image, PDF, or rendered content.
- Choose Panther if the capture follows clicks, navigation, JavaScript application behavior, or a test assertion in a real browser.
- Choose Panther for end-to-end test artifacts when screenshot capture is part of PHPUnit-driven test workflows or failure diagnosis.
- Choose based on runtime you can operate. Browsershot needs its Node/Puppeteer/browser chain; Panther needs the browser/WebDriver chain and compatible PHP dependencies.
- Do not choose based on an assumed speed winner. The reviewed sources do not provide a direct benchmark between these two tools.
Symfony also documents alternative clients in the Panther ecosystem. BrowserKit’s kernel client is limited to Symfony apps; HttpBrowser can browse webpages from PHP but lacks JavaScript and other advanced browser capabilities. Symfony characterizes those alternatives as faster, but that is not a speed comparison with Browsershot.
6. Troubleshooting
| Symptom | Likely cause | What to check |
|---|---|---|
| Browsershot cannot launch or exits before saving output | Node, Puppeteer, or the browser executable is missing or not available to the PHP process. | Follow the setup instructions for the installed Browsershot version; check executable availability and runtime paths in the same environment that runs PHP. |
| Panther cannot start a session | Browser or WebDriver is missing, incompatible, or not discoverable. | Confirm the selected browser and driver are installed and compatible, then review the documented installer or manual setup route. |
| Screenshot is blank or missing a section | Capture happened before the application rendered the required state, or assets did not load. | For Panther, wait for a relevant element or its visibility. For either tool, verify asset URLs and network access from the runtime. |
| Assets are missing under Panther’s built-in PHP server | Symfony notes the built-in server can return 404 for assets outside the public directory. | Compile assets or configure a router script as described in Symfony’s end-to-end testing guide. |
| Local screenshots differ from CI | Runtime dependencies, browser versions, asset availability, or page readiness differ. | Make browser and driver setup explicit in CI, compare loaded assets, and wait for application state before capture. |
| Panther interaction code fails on a page feature | Some Panther limitations affect XML crawling and certain form or DOM operations. | Check the documented limitations for the operation in question and whether the page can be exercised through the supported browser client flow. |
| Containerized Chrome fails with sandbox errors | The container’s security/runtime configuration may prevent Chrome from starting normally. | Review Symfony’s container guidance and the security implications of any sandbox configuration before changing it. |
7. Performance, reliability, and cost
Both approaches depend on launching or controlling a browser, loading the target page, and waiting for the required resources or application state. Those steps dominate many capture workflows, but the sources here do not establish comparative timings, resource consumption, or reliability rates. Measure against your own pages and deployment environment if those factors decide the architecture.
For reliability, make the capture condition explicit: wait for the content you need, ensure dependencies and assets exist in the runtime, and preserve error screenshots or logs when a test fails. Panther’s test integration provides a natural place for failure artifacts. Browsershot is straightforward when the requested output is simply a rendered page or supplied HTML.
Neither package’s supplied research establishes a hosted-service price comparison. For self-hosted use, account for engineering and CI time spent maintaining PHP dependencies and browser runtimes. For a managed API option, ScreenshotNeo lists a free tier and paid plans; details are below.
8. Or skip the browser setup
If you only need a screenshot from a URL, ScreenshotNeo is a website screenshot API and MCP server for developers. Make one GET request:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for the request and available options. The same request in Python:
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)
And in 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}`);
ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for 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 screenshots.
Sign up free for 1,000 screenshots a month, no card required.
9. FAQ
Can Panther run without a Symfony application?
Yes. Symfony documents using Panther outside a Symfony application with Composer autoloading. The exact setup still depends on the browser and WebDriver environment.
Can Browsershot render HTML that is not hosted at a public URL?
Yes. Its repository documents raw HTML input and a local HTML file, in addition to a URL.
Which one should I use for a screenshot after clicking a button?
Panther is the natural fit when the screenshot depends on a browser interaction and the resulting application state.
Is one faster?
The reviewed sources do not provide a head-to-head benchmark, so there is no supported overall speed winner.
Can either capture a PDF?
Browsershot’s repository describes image and PDF output. ScreenshotNeo also supports PDF capture through its API and MCP tool.
