CaptureKit vs Browsershot for HTML-to-Image Screenshots
Compare CaptureKit’s hosted screenshot API with Browsershot’s PHP and Puppeteer workflow, see runnable examples, and choose the right fit for HTML-to-image capture.
Short answer: CaptureKit is a hosted API for capturing a URL as an image or PDF. Browsershot is a PHP package that renders a URL or supplied HTML through Puppeteer running headless Google Chrome. Choose CaptureKit when you want an API workflow and do not want to manage the browser layer in your application. Choose Browsershot when you need its PHP package workflow, especially rendering generated HTML or a local HTML file. Neither product can be called faster, more reliable, cheaper, or more visually faithful on the available documentation alone.
This guide compares their documented operating models and shows how to get an HTML-to-image screenshot with each. It also covers the practical questions to resolve before production: input type, output controls, browser ownership, errors, workload testing, and cost.
1. CaptureKit vs Browsershot: the core difference
| Question | CaptureKit | Browsershot |
|---|---|---|
| How do you call it? | Send an authenticated request to a hosted screenshot endpoint. | Call a PHP package in an application; it uses Puppeteer and headless Chrome. |
| What input is documented? | A URL parameter for the screenshot endpoint. | A URL, arbitrary HTML, or HTML loaded from a local file. |
| Who owns the browser runtime? | The API provider operates the capture service; the caller does not set up headless Chrome for this API flow. | Your application environment must support the package’s Puppeteer and Chrome rendering basis. |
| What controls are documented? | Output format, viewport and device emulation, full-page capture, selector capture, waits, resource controls, caching, and optional storage. | The reviewed repository establishes URL and supplied-HTML rendering, plus reading body HTML after JavaScript has run; it is not a complete feature-by-feature matrix. |
| What does the evidence say about cost or speed? | The endpoint documentation says one credit per call. The dossier does not establish plan prices or comparable total cost. | No comparable throughput or total-cost figure was established. |
Sources: CaptureKit Capture API reference and Spatie Browsershot repository. The comparison describes documented capabilities, not independently tested output.
2. Choose based on input and runtime ownership
Start with CaptureKit when
- Your input is a publicly reachable or otherwise API-accessible URL.
- You prefer an HTTP request over installing and operating a headless-browser stack alongside your application.
- You need documented API controls such as device emulation, viewport size, full-page capture, element selection, waits, resource blocking, caching, or optional S3-compatible output.
Start with Browsershot when
- Your application is PHP-based and you want to invoke rendering through a PHP package.
- You need to render arbitrary HTML or a local HTML file, not only submit a URL.
- You want package-level control over the rendering workflow and can account for Puppeteer and headless Chrome in your runtime and deployment.
For either option, verify the exact version-specific documentation before committing. A capability listed in one product’s documentation does not establish that the other product lacks it; the available Browsershot research is not a full parity audit.
3. Capture a URL with CaptureKit
The documented CaptureKit screenshot endpoint accepts an API key in the x-api-key header and a URL. PNG is the documented default; PNG, JPEG/JPG, WebP, and PDF are listed output types. The endpoint documentation states a metering cost of one credit per call. That statement is not a price-per-image comparison. Check the live endpoint reference for current parameter names, limits, and defaults.
cURL example
curl --get 'https://api.capturekit.dev/v1/capture' \
--header 'x-api-key: YOUR_API_KEY' \
--data-urlencode 'url=https://example.com' \
--data-urlencode 'format=png' \
--output screenshot.png
Use the endpoint’s current documented base URL and parameter names when implementing: API details can change, and the research dossier does not provide a full request schema suitable for asserting every parameter spelling. The example shows the request shape; consult the linked API reference for a runnable request against the current service.
4. Render a URL, HTML string, or file with Browsershot
Browsershot’s repository documents rendering a URL, arbitrary HTML, and a local HTML file through the PHP package. Install and runtime setup depend on your project and deployment environment; follow the repository’s current installation instructions for Puppeteer and Chrome configuration.
URL input
<?php
use Spatie\Browsershot\Browsershot;
Browsershot::url('https://example.com')
->save('screenshot.png');
Supplied HTML input
<?php
use Spatie\Browsershot\Browsershot;
$html = '<!doctype html>
<html>
<head><meta charset="utf-8"><title>Card</title></head>
<body><main><h1>Monthly report</h1><p>Revenue: $42,000</p></main></body>
</html>';
Browsershot::html($html)
->save('report.png');
Local HTML file input
<?php
use Spatie\Browsershot\Browsershot;
Browsershot::htmlFromFile(__DIR__ . '/report.html')
->save('report.png');
These examples show the repository’s documented input modes. For dimensions, selectors, waits, or other rendering options, consult the current Browsershot repository documentation and confirm the methods available in the package version installed by your application.
5. Make screenshots consistent and useful
A capture is only meaningful when its inputs are controlled. Before integrating either choice, write down the output contract and test representative pages against it.
- Fix the target and state. Decide whether the source is a URL, generated HTML, or a file, and whether the page needs authentication or application data before it can render.
- Specify the output. Choose image versus PDF, viewport or device, and full-page versus a particular element. CaptureKit documents these controls; confirm which ones are available in your chosen Browsershot version.
- Wait for actual readiness. Pages may depend on JavaScript, fonts, API responses, or lazy-loaded images. CaptureKit documents wait conditions, delays, and full-page scrolling options. In either system, validate that the chosen readiness condition matches the page rather than relying on an arbitrary short delay.
- Decide what resources to load. Blocking ads, trackers, or other requests can reduce unnecessary work, but blocking a required stylesheet, font, or API call can change the image. CaptureKit documents resource and URL blocking controls.
- Test the error path. Treat navigation failure, an incomplete render, and an intentionally empty page as separate outcomes in your application. Do not save a response as an image unless it is actually a successful image.
6. Deployment, reliability, and performance considerations
There is no workload-matched benchmark in the available research, so measure with your own pages and concurrency before choosing on performance. A useful comparison uses the same target URLs, viewport, output format, wait rule, and repetitions, and records failures as well as successful capture time. Record the test date and relevant package or endpoint settings if you publish results.
- With a hosted API: your application makes network requests and must handle request timeouts, provider responses, and transient failures. Browser installation and patching are outside the caller’s API workflow, but the application still needs monitoring and retry rules appropriate to its use.
- With Browsershot: include Puppeteer and headless Chrome in deployment planning. Consider installation, runtime compatibility, process limits, memory, concurrency, browser updates, and cleanup of temporary files. These are operational questions implied by running the documented browser stack; the research does not quantify their cost or burden.
- For both: bound concurrency, set sensible timeouts, avoid unbounded retries, and make capture jobs observable. Keep per-capture inputs such as URL, output settings, and failure reason in logs without exposing secrets.
- For dynamic pages: use a readiness condition tied to the content you need. A fixed delay can waste time on fast pages and still be too short for slow ones.
7. Cost: compare the whole workflow
CaptureKit’s endpoint reference says one credit per call, but the research did not verify current plan prices, quotas, or overage terms. It also did not establish Browsershot’s total operating cost. Do not compare one API credit with a browser package as if those were equivalent units.
Estimate your own monthly workload using expected capture volume, retries, peak concurrency, output storage, and engineering/operations time. For a fair cost comparison, include the infrastructure and maintenance required to run the Browsershot browser stack, and check CaptureKit’s current commercial terms directly. No price winner is established here.
8. Troubleshooting common screenshot failures
| Symptom | Likely cause | What to check |
|---|---|---|
| CaptureKit rejects the request | Missing or invalid API key, malformed URL, or parameter outside the documented constraints. | Send the key using the documented x-api-key header; verify URL encoding and current parameter names and limits in the API reference. |
| Image is blank or missing content | The page has not rendered its content when captured, or required scripts/data did not load. | Check the page in a normal browser, then configure an appropriate wait/readiness condition and verify any blocked resources. Do not assume a fixed delay guarantees readiness. |
| Page is cut off | The capture uses a viewport-sized image instead of full-page capture, or the page content extends beyond the selected area. | Enable documented full-page behavior where supported, or select the intended element. Check lazy-loaded content and scrolling behavior. |
| Fonts or styling differ | Stylesheets, fonts, or other resources were unavailable or blocked; the page may also be rendered under a different viewport/device setup. | Allow required resources, check the target’s network dependencies, and make viewport/device settings explicit. |
| Browsershot cannot launch Chrome | The required Puppeteer/Chrome runtime is not installed or is not configured for the execution environment. | Follow the package’s current installation and deployment guidance; verify that the runtime user can access the configured browser executable and required files. |
| Local HTML output differs from a hosted page | Relative asset paths, scripts, or data assume a particular base URL or server context. | Use valid asset URLs or a suitable base path, and check which requests the HTML makes when rendered. |
| Intermittent timeouts | Slow navigation, long-running page scripts, resource failures, or excessive concurrency. | Record the target and capture settings, set bounded timeouts, investigate slow dependencies, reduce concurrency, and retry only transient failures with a limit. |
| Capture cost or credit usage is unclear | Endpoint metering has been mistaken for total cost or plan terms. | Use the current provider pricing and quota documentation; the available research only establishes CaptureKit’s one-credit-per-call endpoint statement. |
9. ScreenshotNeo: an alternative to try first
If you want a hosted screenshot API with clean-page handling and clear billing outcomes, try ScreenshotNeo first. It is a website screenshot API and MCP server from Yorker Media. Its API accepts one GET request with a URL and returns PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API documentation for request options and configuration.
For a CaptureKit-versus-Browsershot decision, the practical distinction remains managed API versus PHP-controlled browser rendering. ScreenshotNeo is another managed API option to evaluate when consent cleanup, billing only for clean shots, and agent access matter. No comparative speed or fidelity claim is implied.
Or skip the browser setup
Make one request to capture a URL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Equivalent 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)
Equivalent 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 import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));
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 cleanup step can be turned off. Bot checks and 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. Every plan includes every feature; 1,000 screenshots a month are free with no card, and paid plans start at $5 for 3,000. Sign up for free and get 1,000 screenshots a month with no card.
10. FAQ
Can Browsershot render HTML without hosting it at a URL?
Yes. The repository documents arbitrary HTML input and HTML loaded from a local file, in addition to URL input.
Does CaptureKit charge one credit for every screenshot?
Its endpoint documentation states one credit per call. That does not establish a plan’s monetary price, included quota, or total workflow cost.
Which option is more reliable?
The research does not establish a reliability winner. Test representative pages and failure conditions in the environment and workload you expect to use.
Can I use either one for PDFs?
CaptureKit’s endpoint lists PDF as an output format, and Browsershot describes converting pages to images or PDFs. Check each current product’s documentation for the precise controls you need.
Sources and scope
- CaptureKit Capture (Screenshot) API reference
- CaptureKit product page
- Spatie Browsershot official repository
The CaptureKit and Browsershot comparison is based on those official materials as summarized in the research dossier. No products were run for this article, and no comparative test of performance, fidelity, reliability, or total cost is claimed. The ScreenshotNeo section uses only the product facts supplied for this assignment.
