BLOG
Browser Use vs Playwright: Agent Framework or Automation Library
Browser Use vs Playwright compared: what each layer does, where they overlap, and how to run either against hosted Chromium in production.

The browser use vs Playwright question usually comes from a false premise: that these are competing tools you pick between. They are not the same layer of the stack. Playwright is a browser automation library — it drives Chromium, Firefox, and WebKit through a typed API and the Chrome DevTools Protocol. Browser Use is an agent framework that sits on top of a browser driver and lets an LLM decide what to click, type, and read. Most production systems that "use Browser Use" are also using Playwright or a CDP client underneath.
So the useful comparison is not "which one wins." It is: which layer do you need, what does each assume about the browser it runs against, and what breaks when you move from a laptop to a fleet of concurrent sessions? This guide answers that, then shows how to run both against a hosted Chromium runtime so the browser itself stops being the variable.
The short answer
- Use Playwright when the task is deterministic: form fills, regression tests, scraping a known DOM, scheduled jobs with fixed steps. You want explicit selectors, assertions, and reproducible runs.
- Use Browser Use when the task is open-ended: "find the cheapest flight that meets these constraints," "log in and reconcile these invoices," "research this company and fill the form." The steps are not known ahead of time, so an LLM plans them at runtime.
- Use both when you want an agent for planning and Playwright for the deterministic sub-steps it hands off. This is common in production because agents are unreliable at precise, repeated interactions and libraries are bad at improvisation.
Neither choice removes the operational problem: you still need a real browser, isolated per session, reachable over CDP, with profiles, proxies, and a way to watch what happened. That is the runtime layer, and it is where most teams actually lose time.
What Playwright actually is
Playwright is a Node/Python/Java/.NET library that launches or connects to a browser and exposes a high-level API: page.goto(), page.click(), locator().fill(), expect(). It speaks CDP to Chromium and its own protocol to Firefox and WebKit. It ships with auto-waiting, tracing, and a test runner.
Key properties for this comparison:
- Deterministic by design. Every action is code you wrote. There is no model in the loop unless you add one.
- Selector-driven. You target elements by role, text, CSS, or test ID. When the DOM changes, the script breaks loudly — which is what you want in tests.
- Browser-agnostic. Chromium, Firefox, WebKit. Browser Use is effectively Chromium-only in practice because it depends on CDP-level control and DOM extraction.
- Connectable.
chromium.connectOverCDP(endpointURL)attaches to an already-running browser instead of launching one. This is the hook that makes remote and hosted runtimes possible.
That last point matters. Playwright does not require you to install browsers locally if you connect to a remote endpoint. The library is the client; the browser can live anywhere.
What Browser Use actually is
Browser Use is an open-source Python framework (with a hosted cloud offering) that gives an LLM a browser as a tool. You give it a task in natural language; it observes the page — typically via DOM extraction and/or screenshots — asks the model for the next action, executes it through a browser driver, and repeats until the task completes or it hits a step limit.
Key properties:
- Non-deterministic by design. The same task can take different paths on different runs. That is the point: it handles pages you did not anticipate.
- Model-dependent. Output quality tracks the model's ability to reason over page state. Token cost scales with steps and page size.
- Driver-dependent. Under the hood it needs a browser it can control. Historically that has meant Playwright or a CDP connection, and the hosted product exposes cloud browsers you drive over CDP.
- Harder to test. You cannot assert "this selector was clicked." You assert outcomes, and outcomes are probabilistic. Evaluation requires task-level success metrics, not unit tests.
If you have read our agent browser vs Browser Use breakdown, the framing is the same: the framework is the brain, the runtime is the body.
Side-by-side comparison
| Dimension | Playwright | Browser Use |
|---|---|---|
| Layer | Automation library / driver client | Agent framework (LLM planner + driver) |
| Determinism | Fully deterministic | Probabilistic |
| Who decides the next step | Your code | The model |
| Browsers supported | Chromium, Firefox, WebKit | Chromium in practice |
| Best fit | Tests, scraping, fixed workflows | Open-ended tasks, research, form filling on unfamiliar sites |
| Failure mode | Selector timeout, assertion failure | Wrong action, loop, step-limit exhaustion |
| Debugging | Traces, videos, step-through | Session recordings, step logs, live viewer |
| Cost model | Compute only | Compute + model tokens per step |
| Testability | Unit and integration tests | Task-level evals |
| Remote support | connectOverCDP to any endpoint | Cloud browsers via CDP |
| Learning curve | Low if you know the DOM | Low to start, high to make reliable |
The row that decides most architecture debates is "who decides the next step." If you can enumerate the steps, Playwright is cheaper, faster, and far easier to keep green. If you cannot, you need a model in the loop and you accept the reliability tax.
Where the two overlap — and where they don't
Overlap: both need a live browser, both can drive it over CDP, both benefit from persistent profiles (logged-in state), proxies, and session isolation. Both suffer when the browser is a local Chrome instance on a developer machine that cannot be parallelized or observed.
No overlap: Playwright will never decide to try a different navigation path because a button moved. Browser Use will never give you a stable assertion that a specific element was present at step 4. Teams that expect one to do the other's job end up rewriting.
A practical pattern that shows up repeatedly in production:
- The agent (Browser Use or a custom loop) handles discovery: find the right page, identify the form, decide what data to enter.
- The agent hands off to a Playwright function with explicit selectors for the actual submission, because the last mile must not be flaky.
- The result is verified by a Playwright assertion, not by asking the model whether it worked.
This hybrid keeps token spend down and makes the critical path testable.
The runtime problem neither tool solves
Here is the part that gets buried. Whether you pick Playwright or Browser Use, you need:
- A real Chromium per session, isolated so cookies and storage do not leak between tenants or tasks.
- A CDP endpoint you can connect to from wherever your code runs — a worker, a container, a serverless function.
- Persistent profiles so agents do not re-authenticate on every run.
- Configurable browser settings for proxy routing and session behavior, since many target sites behave differently by IP and region.
- A live viewer so a human can watch a run in progress and intervene when the agent stalls.
- Usage controls so a runaway agent loop does not quietly burn hours.
Running this yourself means container orchestration, Chromium version pinning, zombie-process reaping, and a viewer you build. That is the infra tax. A hosted runtime like Remote Browser exists to absorb it: you request a session, get a CDP WebSocket URL, and connect with whichever client you prefer. See Remote Browser for AI agents for the architecture, and /documentation for the connection details.
Connecting Playwright to a hosted browser
The code is short. The important part is that connectOverCDP gives you a Browser object you drive exactly like a locally launched one — contexts, pages, locators, assertions all work.
import { chromium, type Browser, type Page } from "playwright";
interface SessionInfo {
cdpUrl: string; // wss://... from your runtime's session API
}
async function runTask(session: SessionInfo): Promise<void> {
let browser: Browser | undefined;
try {
// Attach to the hosted Chromium instead of launching locally.
browser = await chromium.connectOverCDP(session.cdpUrl);
// Reuse the existing context so persistent profile state is preserved.
const context = browser.contexts()[0] ?? (await browser.newContext());
const page: Page = context.pages()[0] ?? (await context.newPage());
await page.goto("https://example.com/login", { waitUntil: "domcontentloaded" });
await page.getByLabel("Email").fill(process.env.APP_EMAIL!);
await page.getByLabel("Password").fill(process.env.APP_PASSWORD!);
await page.getByRole("button", { name: "Sign in" }).click();
// Assert on outcome, not on timing.
await page.waitForURL("**/dashboard", { timeout: 15_000 });
const heading = await page.getByRole("heading", { level: 1 }).innerText();
if (!heading.includes("Dashboard")) {
throw new Error(`Unexpected landing page: ${heading}`);
}
} finally {
// Close the connection, not the remote browser, unless you own its lifecycle.
await browser?.close();
}
}Two details worth internalizing. First, browser.close() on a CDP connection detaches your client; whether the remote session terminates depends on the runtime's session semantics — check your provider's docs before assuming. Second, reusing contexts()[0] is what makes persistent profiles useful; creating a fresh context each run throws away the login state you paid to establish.
For the full set of connection options, the Playwright CDP documentation is authoritative and worth reading once end to end.
Running Browser Use against a hosted browser
Browser Use's hosted offering exposes cloud browsers you drive over CDP, and the open-source framework can be pointed at a CDP endpoint too. The pattern is the same as above: the framework gets an endpoint, not a local Chrome binary. What changes is what you monitor.
For agent workloads, instrument these:
- Step count and token spend per task. A task that takes 40 steps instead of 8 is usually a page-state extraction problem, not a model problem.
- Loop detection. Agents get stuck clicking the same element. Cap steps and fail fast.
- Page-state size. Dumping the full DOM into context is expensive; extract interactable elements only.
- Session recordings. When an agent fails, you need to see the page it saw, not just the action log.
A hosted runtime with a live viewer and session recordings shortens this loop considerably, because you can watch a failing run in real time rather than reconstructing it from logs.
Decision criteria for production
Work through these in order:
- Can you enumerate the steps? If yes, Playwright. If no, you need an agent.
- How often does the target site change? Stable DOM favors Playwright; volatile or unfamiliar sites favor an agent.
- What is the cost of a wrong action? Irreversible actions (payments, deletions, submissions) should be Playwright with explicit confirmation, regardless of what planned them.
- What is your eval story? Playwright gives you pass/fail tests. Agents need task-level success rates over a sample set. If you cannot measure success, you cannot ship an agent.
- Where does the browser run? If you are managing containers, version pinning, and a viewer, you are paying the infra tax. Compare that against a metered runtime — see /pricing for current rates rather than guessing.
A common outcome: teams start with Browser Use because it demos well, discover that 20% of tasks need deterministic handling, and end up with a hybrid where Playwright owns the critical path. That is not a failure of the framework; it is the correct division of labor.
Common mistakes
- Treating Browser Use as a Playwright replacement. It is a consumer of browser drivers, not a substitute for them. You will still write selectors for the parts that must be reliable.
- Running agents against local Chrome. No isolation, no parallelism, no viewer, and the session dies with your laptop. See remote browser online for what the hosted alternative looks like.
- Skipping persistent profiles. Re-authenticating on every run multiplies steps and failure surface. Profiles are the single highest-leverage reliability fix for agent workloads.
- No step cap. An agent without a step limit is an unbounded cost. Set one.
- Asserting with the model. "Did it work?" answered by an LLM is not a test. Assert on URL, DOM state, or a downstream system effect.
Bottom line
Browser Use vs Playwright is a layer question, not a winner question. Playwright is the deterministic driver you trust for the last mile; Browser Use is the planner you reach for when the path is unknown. Most production systems need both, and both need a browser runtime that is isolated, observable, and reachable over CDP.
If you are spending more time on Chromium containers than on agent logic, that is the signal to move the browser out of your infrastructure. Start with the remote browser overview, then wire your client of choice to a hosted session and measure the difference in your own task success rate.