Browser rendering without the boilerplate
Taking screenshots of web pages is a deceptively hard engineering problem. It’s easy enough in a local browser, but automating it for production use—saving dashboard snapshots, generating social media previews, capturing bug reports—means standing up a full browser stack that runs on demand.
Cloudflare is addressing that with the Workers Browser Rendering API, now in private beta. The Rendering API, as it’s called, runs browser automation inside Workers. With it, a screenshot workflow can be expressed in a few lines of code and deployed to Cloudflare’s edge network.
Where automated browsers earn their keep
Cloudflare’s own teams needed this internally for dashboard screenshots, social sharing thumbnails, and UI bug capture—requests that came from engineering leadership and product teams alike. Those needs revealed a broader set of automation use cases:
- E2E testing: Simulating real user behavior to catch defects that unit tests miss, particularly on critical paths like account creation, authentication, and checkout.
- Performance regression checks: Measuring page load time and related metrics in production-like conditions before merging code that could degrade latency.
- Continuous reporting: Emailing dashboard screenshots on a schedule, without human involvement.
Why this is harder than it looks
Puppeteer is the standard framework for browser automation, but it’s typically run inside containerized environments or serverless platforms. Neither is turnkey. On AWS Lambda, you need to package Puppeteer, ensure dependencies are present, upload to S3, and manage Layers for deployment. Docker gives you more control but requires infrastructure to run containers on demand.
The Rendering API removes that operational layer. It brings Puppeteer into the Workers platform, so automation runs where your other code runs, without provisioning or dependency management. The beta supports navigating to pages and taking screenshots, with full Puppeteer methods (including page.type, page.click, and page.evaluate) planned.
Configuration and quick start
The setup is a browser binding added to wrangler.toml:
bindings = [
{ name = "my_browser” type = "browser" }
]
From there, navigating to a page and saving the result to R2 is straightforward:
import puppeteer from '@cloudflare/puppeteer'
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const browser = await puppeteer.launch({
browserBinding: env.MY_BROWSER
})
const page = await browser.newPage()
await page.goto("https://example.com/")
const img = await page.screenshot() as Buffer
await browser.close()
//upload to R2
try {
await env.MY_BUCKET.put("screenshot.jpg", img);
return new Response(`Success!`);
} catch (e) {
return new Response('', { status: 400 })
}
}
}
Architecture and isolation
Under the hood, the API borrows from Cloudflare’s remote browser isolation technology, used in its Zero Trust offering. The Worker acts as a client. Each data center keeps a pool of warm browsers available for immediate assignment; once a browser is returned, the Worker connects to it over a WebSocket. From that moment, an internal browser API Worker proxies all communication to the session through the Chrome DevTools Protocol.
Security was a design constraint:
- Each Worker request gets a **disposable, dedicated browser instance**—never shared between requests.
- The browser runs under **gVisor**, which guards against kernel-level exploits.
- Processes are sandboxed with the lowest privilege level via a **Linux seccomp profile**.
Because these automation sessions could be misused, Cloudflare Bot Management can flag traffic originating from a Worker running Puppeteer. A request with those signals can be automatically added to a customer’s blocklist, with the option to explicitly allow it.
The Rendering API navigates to a page and captures it, handling the isolation, connection, and cleanup for you. The code that runs between request and response—the screenshot itself—is what you’re left to write. Product teams that need recurring, unattended captures of web content now have a dedicated building block rather than a server to manage.



