BLOG
Browserless Steel: Hosted Chromium for AI Agents
Browserless Steel explained: how Steel's open-source browser runtime compares to hosted Chromium for AI agents, plus a Playwright CDP setup guide.
# Browserless Steel: Hosted Chromium for AI Agents
"Browserless Steel" is a search phrase that mixes two different things: Browserless, a long-running headless browser service, and Steel, an open-source browser API you can self-host. Developers usually land on it while comparing runtimes for AI agents and browser automation. The short answer: Steel is a self-hosted browser API you run yourself, while Browserless is a managed service. Neither is a drop-in runtime for agent workloads that need persistent profiles, live debugging, and per-session isolation without you operating the infrastructure. That gap is what hosted Chromium runtimes like Remote Browser fill.
This guide explains what Steel actually is, where it fits, how it compares to Browserless and hosted options, and how to wire a Playwright agent to a remote Chromium session over CDP.
What "Browserless Steel" actually refers to
The phrase is a collision of two projects:
- Browserless — a managed headless browser service. You send it automation jobs or connect over CDP/WebSocket, and it runs Chromium (and Firefox/WebKit in some configurations) on its infrastructure. It has been around since the Puppeteer era and is widely used for scraping and screenshot pipelines.
- Steel — an open-source browser API. You deploy it yourself (Docker, a VM, or a Kubernetes cluster), and it exposes an HTTP/CDP interface for driving Chromium sessions. Steel is closer to "a browser API you own" than "a browser service you rent."
So "Browserless Steel" is not a product. It is a comparison query. The real question behind it is: *should I self-host a browser API like Steel, use a managed service like Browserless, or run agents on a hosted Chromium runtime?*
Those three options solve different problems, and the right answer depends on whether your bottleneck is infrastructure, agent reliability, or both.
Steel vs Browserless vs hosted Chromium
Here is the practical breakdown. Treat it as a decision table, not a scorecard.
| Dimension | Steel (self-hosted) | Browserless (managed) | Hosted Chromium runtime |
|---|---|---|---|
| Who runs the browser | You | Vendor | Vendor |
| Primary interface | HTTP API + CDP | CDP/WebSocket + REST | CDP + Playwright/Puppeteer/Selenium |
| Session isolation | You configure it | Per-connection | Per-session by default |
| Persistent profiles | You build storage | Limited | Built-in profile persistence |
| Live viewer / debugging | You add it | Varies | Included |
| Proxy & browser settings | You wire it | Configurable | Configurable per session |
| Ops burden | High | Low | Low |
| Best fit | Teams with infra control | Scraping, screenshots | AI agents, browser-use workflows |
The important row is the last one. Steel and Browserless are both *browser execution* layers. A hosted Chromium runtime for agents is a *session lifecycle* layer: it manages profiles, proxies, isolation, and observability so an agent can retry, resume, and debug without you rebuilding that plumbing.
If you are running a scraping fleet, Steel or Browserless may be fine. If you are running an agent that logs into a site, keeps a session alive across steps, and needs a human to watch it fail, you want the session layer.
Why self-hosting Steel gets expensive in agent workloads
Steel is genuinely good software. The problem is not the code; it is the operational surface area once agents are the client.
Agents are long-lived and stateful. A scraping job is short and stateless. An agent session may span dozens of navigations, form fills, and retries. That means you need persistent browser profiles, cookie storage that survives a worker restart, and a way to reattach to a session after a crash. Steel gives you the browser; you still build the state layer.
Agents need to be watched. When an agent gets stuck on a modal or a CAPTCHA, you need to see the live page. Self-hosted Steel does not ship a viewer. You either build one or debug from logs, which is slow.
Agents multiply concurrency. Ten scraping workers is a small cluster. A hundred concurrent agent sessions is a scheduling, memory, and isolation problem. You will be tuning container limits, Chromium flags, and zombie-process reaping instead of improving your agent.
Agents need clean egress. Many target sites treat datacenter IPs differently. You will want per-session proxy configuration and consistent browser settings. That is configurable in a hosted runtime; in self-hosted Steel it is another thing you own.
None of this is a knock on Steel. It is the standard trade-off: open source gives you control, and control costs engineering time. The question is whether browser infrastructure is your differentiator. For most agent teams, it is not.
What a hosted Chromium runtime adds
A hosted runtime like Remote Browser is built around the assumption that the browser is infrastructure, not the product. Concretely, that means:
- Hosted Chromium sessions you start via API and connect to over CDP.
- Playwright, Puppeteer, and Selenium compatibility — you keep your existing automation code.
- Persistent profiles so logins and cookies survive across sessions.
- A live viewer so you can watch and debug a running session in real time.
- Configurable browser and proxy settings per session, including stealth-related options where supported.
- Session isolation so one agent's cookies and storage never leak into another's.
- Usage controls so you can meter and cap browser time.
If you want the longer version of why this layer exists, see Remote browsers for AI agents. The point here is narrower: it is the layer Steel and Browserless leave you to build.
Connecting a Playwright agent over CDP
The reason hosted runtimes are practical is that they speak standard protocols. You do not adopt a new SDK; you point Playwright at a WebSocket endpoint. The Chrome DevTools Protocol is the underlying transport, and Playwright's connectOverCDP is the supported entry point — see the Playwright CDP documentation for the API surface.
Here is a minimal TypeScript example. It assumes your runtime returns a CDP WebSocket URL for a session.
import { chromium, Browser, Page } from 'playwright';
interface SessionInfo {
cdpUrl: string; // wss://... from your runtime's session API
sessionId: string;
}
async function runAgentTask(task: (page: Page) => Promise<void>) {
// 1. Ask the runtime for a session. In production this is an API call
// that returns a CDP endpoint plus a session id you can reuse.
const session: SessionInfo = await createSession({
// Persistent profiles let logins survive across runs.
profile: 'checkout-agent',
// Proxy and browser settings are configured per session.
proxy: { country: 'us' },
});
let browser: Browser | undefined;
try {
// 2. Connect over CDP. No local Chromium download required.
browser = await chromium.connectOverCDP(session.cdpUrl);
// 3. Reuse the existing context so profile state is preserved.
const context = browser.contexts()[0] ?? await browser.newContext();
const page = context.pages()[0] ?? await context.newPage();
await task(page);
} finally {
// 4. Close the connection. The session lifecycle is managed
// by the runtime, not by your worker process.
await browser?.close();
}
}
// Minimal session helper — replace with your runtime's real API.
async function createSession(opts: {
profile: string;
proxy?: { country: string };
}): Promise<SessionInfo> {
const res = await fetch('https://api.remote-browser.dev/sessions', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(opts),
});
if (!res.ok) throw new Error(`session create failed: ${res.status}`);
return res.json() as Promise<SessionInfo>;
}Three details matter in production:
- Reuse `browser.contexts()[0]`. When you connect over CDP to an existing browser, a context already exists. Creating a new one discards the profile state you paid to persist.
- Do not call `browser.close()` expecting to kill the remote browser. Over CDP, closing the connection detaches your client. Session teardown is a separate API call in most runtimes.
- Treat the CDP URL as a secret. It grants full control of that browser session. Fetch it per run and do not log it.
If you are still deciding between a local install and a remote endpoint, Remote Browser online covers the setup differences.
Production criteria before you pick a runtime
When you evaluate Steel, Browserless, or a hosted runtime, score them against these criteria rather than feature lists:
- Session lifecycle API. Can you create, list, reattach to, and terminate sessions programmatically? Reattachment is the one that separates agent runtimes from scraping tools.
- Profile persistence. Do cookies and localStorage survive a worker restart? Test it explicitly.
- Observability. Is there a live viewer, and can you get session recordings or logs after the fact?
- Isolation guarantees. Are sessions isolated by default, or is that your responsibility?
- Egress control. Can you set proxies and browser settings per session, and does the runtime document what is and is not configurable?
- Protocol compatibility. Does it speak CDP so your Playwright/Puppeteer/Selenium code ports without a rewrite?
- Cost model. Browser time is metered. Understand whether you pay per session-hour, per task, or per connection. Check /pricing for current rates rather than relying on blog numbers.
If a runtime fails the reattachment test, it is a browser executor, not an agent runtime. That is the cleanest line between the two categories.
When Steel or Browserless is still the right call
Be honest about your situation. Self-hosting Steel makes sense when:
- You have strict data-residency or network-isolation requirements and cannot send traffic to a third party.
- Browser infrastructure *is* your product, and you want to own the full stack.
- Your workloads are short, stateless, and high-volume — classic scraping rather than agentic.
- You already run a Kubernetes platform and adding a browser service is marginal work.
Browserless makes sense when you want a managed executor for scraping and screenshot pipelines and do not need persistent agent sessions.
A hosted Chromium runtime makes sense when your client is an agent: stateful, long-running, retry-heavy, and in need of a human watching the live page when it breaks. That is the workload the session layer was built for.
The practical takeaway
"Browserless Steel" is a comparison, not a product. Steel is an open-source browser API you operate; Browserless is a managed executor; neither is a session lifecycle layer for AI agents. If your workload is scraping, either is reasonable. If your workload is an agent that logs in, persists state, and needs live debugging, the infrastructure you actually want is hosted Chromium with persistent profiles, CDP access, and a viewer.
Start by reading the documentation to see how sessions, profiles, and CDP endpoints are exposed, then wire your existing Playwright code to a remote endpoint using the pattern above. If you want to compare the broader category first, remote web browser and remote control browser cover adjacent use cases.