Bun 1.4 brings Bun.WebView and drops Puppeteer for browser automation
New runtime-embedded primitive loads pages, runs JavaScript, and takes screenshots without Playwright. Simon Willison measured how much RAM it costs.

The release of Bun 1.4, the first stable version since the controversial rewrite from Zig to Rust, came packed with new features: Bun.Image, Bun.markdown, Bun.cron(), Bun.Terminal, bun run --parallel, bun audit fix, and more than 2,900 fixes, according to the release notes. But the addition that most caught the attention of those who work with automation and data collection was Bun.WebView: first-class support for browser automation embedded in Bun's core.
Simon Willison, in a blog post on August 20, 2026, put the feature to the test by building a ~150-line TypeScript HTTP API with zero dependencies that replicates the behavior of his shot-scraper CLI. The result shows something relevant for everyday use: you can load a page, run arbitrary JavaScript on it, and take screenshots without installing Puppeteer or Playwright.
How Bun.WebView Works Under the Hood
Bun.WebView doesn't reinvent the rendering engine. It uses two backends depending on the operating system:
- On macOS, it controls the system's native WebKit (the same engine used by Safari).
- On other platforms, it controls a local Chromium process via the Chrome DevTools Protocol (CDP), the same protocol Puppeteer and Playwright use under the hood.
The difference lies in where the orchestration lives. Instead of an entire Node library mediating the conversation with the browser, Bun embeds that layer into the runtime itself. For developers, that means one less import in package.json and a much leaner node_modules, without the hundreds of MB of browser binary downloads that Playwright usually drags along.
The warning is worth noting: the feature is experimental. Experimental APIs in Bun have a history of changing between minor releases, so it's not a candidate for critical production yet.
The Prototype: One Tab Per Request
The server Willison put together (with help from Claude Code for web, as he notes in the post) exposes three routes:
/javascript— loads a URL, executes a snippet of JS on the page, and returns the result as JSON./screenshot— captures the page as PNG, JPEG, or WebP./healthz— service health check.
The concurrency design is the interesting part: the service creates a new browser tab per request. This isolates each call (one heavy page doesn't contaminate the next) and allows requests to be processed in parallel, with results and errors always serialized as JSON. It's the pattern that makes sense for a scraping service or integration testing, where each job needs a clean context.
In practice, a client would send something like { "url": "https://example.com", "javascript": "document.title" } to /javascript and get the page's title back. For those already using shot-scraper on the command line, the semantics are familiar, just now exposed as an HTTP service running on top of Bun's runtime.
The Number That Matters: RAM
Willison stated that part of the motivation was measuring how much memory such a service consumes, since running a full Chrome is never cheap. Testing with cgroups, he arrived at a container of 192MB to 256MB to handle an entire Chrome instance against complex pages.
This number is the most useful data point from the experiment for anyone sizing infrastructure. Running browser automation in small containers is notoriously risky (Chrome loves to blow through OOM on heavy pages), and having a concrete range as reference helps set container limits before the service starts dying in production. Still, it's a one-off measurement: heavier pages, many concurrent tabs, or process leaks can push that ceiling higher.
What This Changes for Builders in Brazil
For Brazilian teams doing scraping, page monitoring, or frontend integration testing, the appeal is direct: fewer dependencies and less build surface. Keeping a Playwright stack up to date, with the right browser binary for each CI environment, is a well-known pain. A runtime-embedded solution reduces that friction.
There's also the infrastructure cost angle: scraping services tend to run in ephemeral containers, and every dependency less and every MB less of image size counts when scaling horizontally. The 192MB to 256MB range per instance gives a starting point for calculating how many replicas fit in a cloud plan.
But the usual skepticism applies. Playwright and Puppeteer aren't heavy for no reason: they deliver mature APIs for waiting on selectors, network interception, device emulation, auto-wait, and a huge ecosystem of plugins (stealth, for example). Bun.WebView is, today, a low-level primitive for loading a page, running JS, and taking a screenshot. Complex automation flows (multi-step login, waiting for specific XHR requests, dealing with anti-bot measures) will probably require a lot of manual code that these libraries already solve.
When It's NOT Worth It
- Critical production now: being experimental, the API can change. Don't tie a business pipeline to it yet.
- Complex automation: if you already rely on advanced Playwright features (traces, auto-wait, network mocking), migrating to a rawer primitive is a regression, not a gain.
- Real cross-browser testing: behavior differs between macOS's WebKit and Chromium via CDP on Linux. Testing on macOS and running on Linux can generate rendering surprises.
For those who want a quick proof of concept for data collection or an internal screenshot service running on top of Bun, though, Willison's experiment shows it's already possible to do this today with very little code. The server's source code is referenced in the original post, and it's a good starting point for adapting the three routes to your needs. It's worth following Bun.WebView's evolution in upcoming releases before betting more chips on it.
Translated from the Brazilian Portuguese original · Read the original
Convex Agent Component: how native memory and RAG work for AI agents
Convex's official component bundles threads, persistent memory, and hybrid vector/text search for those building AI agents, without setting up a parallel vector DB stack.
