← Blog

BLOG

Browser Use Production GitHub: What to Check Before You Ship

Browser use production github repos show what breaks at scale. Learn the production criteria, CDP wiring, and runtime checks before you ship agents.

September 22, 20269 min readRemote Browser

# Browser Use Production GitHub: What to Check Before You Ship

Searching for browser use production github usually means one of two things: you found a repo that runs browser-use locally and now need it to survive real traffic, or you are evaluating open-source agent-browser projects and want to know which parts are production-ready. The honest answer is that most GitHub repos in this space are excellent at the agent loop and thin on the runtime underneath it. They assume a browser exists, is reachable, and stays alive. In production, that assumption is the failure mode.

This guide covers what to look for in a browser use production GitHub repository, how the runtime layer differs from the agent layer, and how to wire a hosted Chromium session into a browser-use style workflow using CDP. If you want the conceptual background first, read Remote browsers for AI agents before continuing.

What "production" actually changes

A browser-use demo and a browser-use production deployment differ in four dimensions, and none of them are about the model.

Session lifetime. A demo opens a browser, runs a task, closes it. Production runs tasks that take minutes, retry after failures, and sometimes need to resume in a session that already has cookies, a logged-in profile, or a half-completed checkout. If the repo assumes a fresh browser per task, you will be rebuilding that assumption.

Concurrency. Ten parallel agents on a laptop is a demo. Ten thousand browser-hours a month is an infrastructure problem: process isolation, memory ceilings, and a scheduler that does not let one runaway agent starve the rest.

Failure surface. Locally, a crash is a stack trace. In production, a crash is a stuck session, a leaked profile, an egress IP that changed mid-task, or a CAPTCHA that silently ate your retry budget. The repo needs to expose enough state to distinguish these.

Observability. When an agent fails at step 14 of 30, you need the DOM, the network log, a screenshot, and ideally a live view of the session. A repo that only returns a final string is not production-grade regardless of how good the agent is.

Reading a browser use production GitHub repo

When you open a candidate repo, scan for these signals before you read the agent code.

SignalDemo-gradeProduction-grade
Browser lifecyclelaunch() per taskConnect to existing session over CDP
Session stateDiscarded on exitPersistent profiles, resumable
Concurrency modelasyncio.gather over N tasksQueue, worker pool, per-session isolation
Failure handlingRetry the whole taskStep-level retry, session recovery
ObservabilityFinal output onlyScreenshots, traces, live viewer, logs
Egress supportNone or env varPer-session egress config
AuthHardcoded credsProfile-based or injected secrets
Cost controlsNoneSession timeouts, usage metering

Most repos score well on the first row and poorly on the rest. That is not a criticism of the authors — the agent loop is the interesting part, and the runtime is undifferentiated work. But it means the runtime is your job, and it is the part that determines whether your agent works on Tuesday at 3am.

The agent layer vs. the runtime layer

It helps to separate concerns explicitly.

The agent layer decides what to do: which element to click, what to type, when to stop. This is where browser-use, agent-browser, and similar projects live. It is model-dependent, prompt-sensitive, and improves as models improve.

The runtime layer provides a browser that is reachable, isolated, persistent where needed, and observable. It is model-independent. It does not care whether the decision came from an LLM, a script, or a human clicking in a viewer.

Production failures cluster in the runtime layer far more often than the agent layer. When an agent "doesn't work," the cause is usually a stale session, a blocked IP, a missing cookie, or a timeout — not a bad decision.

Wiring a hosted session into a browser-use workflow

The practical integration point is CDP. Playwright's `connectOverCDP` attaches to a running Chromium instance over the DevTools Protocol, which means your agent code does not launch a browser at all — it connects to one that already exists.

import { chromium, Browser, Page } from 'playwright';

interface SessionHandle {
  cdpUrl: string;
  sessionId: string;
}

// Your runtime returns a CDP endpoint for a hosted Chromium session.
async function getSession(): Promise<SessionHandle> {
  const res = await fetch('https://api.remote-browser.dev/sessions', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.REMOTE_BROWSER_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      profile: 'checkout-agent',      // persistent profile name
      timeoutSeconds: 900,            // hard session ceiling
      egress: { country: 'us' },      // per-session egress config
    }),
  });
  if (!res.ok) throw new Error(`session create failed: ${res.status}`);
  return res.json();
}

async function runTask(task: string) {
  const { cdpUrl, sessionId } = await getSession();
  let browser: Browser | undefined;

  try {
    browser = await chromium.connectOverCDP(cdpUrl);
    const context = browser.contexts()[0] ?? await browser.newContext();
    const page: Page = context.pages()[0] ?? await context.newPage();

    // Hand the live page to your agent loop.
    await page.goto('https://example.com/checkout');
    await agentLoop(page, task);

    // Capture evidence before teardown.
    await page.screenshot({ path: `/tmp/${sessionId}.png` });
  } catch (err) {
    // Session-level failure: surface it, do not silently retry the task.
    console.error(`session ${sessionId} failed`, err);
    throw err;
  } finally {
    // Disconnect the client; the hosted session is reaped by its own timeout.
    await browser?.close();
  }
}

Three details matter here.

`browser.close()` disconnects, it does not kill the remote browser. With connectOverCDP, closing the client leaves the hosted session running until its timeout or an explicit terminate call. That is usually what you want — it lets you reconnect after a transient network blip — but it also means you must set a session timeout or you will pay for orphaned browsers.

Persistent profiles are the difference between a demo and a workflow. A profile named checkout-agent carries cookies and local storage across sessions. Without it, every run starts logged out, and your agent spends its first five steps re-authenticating.

Egress config belongs at session creation, not in the browser. Changing the egress IP mid-session invalidates the connection and often the auth state. Decide the egress country when you create the session.

If you are still deciding between running Chromium locally and connecting to a hosted one, Remote browser online walks through the trade-offs.

Common failure modes and how to detect them

These are the failures that show up in production browser-use deployments, roughly in order of frequency.

Session leak. The agent crashes, the finally block never runs, and the hosted browser stays alive until its timeout. Detect it by tracking created vs. terminated session IDs and alerting on the delta. Mitigate with a hard timeoutSeconds on every session.

Profile contention. Two agents use the same profile name concurrently and clobber each other's cookies. Detect it by logging profile names per session and asserting uniqueness for write-heavy workflows. Mitigate by namespacing profiles per task type or per user.

Silent auth expiry. The session is alive, the page loads, but the user is logged out and the agent clicks into a login wall. Detect it by asserting on a known post-auth selector before the agent loop starts. This is the single highest-value check you can add.

Egress-induced CAPTCHA. The egress IP is flagged and the target serves a challenge. Detect it by watching for challenge-page selectors and non-200 navigation responses. Mitigate with residential egress where the target warrants it — see Remote browser for how egress selection fits into the runtime.

Timeout cascade. A slow page causes the agent to retry, which creates a new session, which is also slow. Detect it by correlating retry counts with session creation rate. Mitigate with step-level timeouts rather than task-level retries.

Hermes and agent-browser connection issues. If you are running Hermes or a similar agent-browser CLI and the browser "is not working," the cause is almost always the CDP endpoint: wrong URL scheme, a session that already expired, or a client that expects ws:// when the runtime returns wss://. Check the endpoint first, then the session's remaining lifetime, then the network path. Most "not working" reports resolve at step one.

Production criteria checklist

Before you call a browser-use deployment production-ready, verify each of these.

  • Every session has a timeout. No exceptions. Orphaned sessions are the most common cost surprise.
  • Every session has an owner. A task ID, a user ID, or a trace ID that lets you find it later.
  • Auth state is asserted, not assumed. A cheap selector check before the agent loop saves hours of debugging.
  • Profiles are namespaced. Concurrent writers to the same profile is a data race with cookies.
  • Egress is decided at creation. Changing the egress IP mid-session breaks auth.
  • Failures are classified. Session failure, auth failure, and agent failure need different responses.
  • Evidence is captured. Screenshot plus DOM snapshot on failure, at minimum.
  • Usage is metered. You should be able to answer "what did this workflow cost last week" without a spreadsheet.

Remote Browser exposes these as runtime primitives: hosted Chromium sessions with CDP access, persistent profiles, per-session egress configuration, session isolation, a live viewer for debugging, and usage controls. Playwright, Puppeteer, and Selenium clients all connect the same way. Current limits and pricing are on /pricing; the API surface is documented at /documentation.

Where the GitHub ecosystem fits

Open-source browser-use and agent-browser repos are worth using. They encode a lot of hard-won knowledge about how to prompt a model into reliable UI actions, and they improve quickly. The mistake is treating them as a complete stack.

A reasonable production architecture looks like this:

  1. Agent layer — an open-source browser-use or agent-browser repo, pinned to a version you have tested.
  2. Runtime layer — hosted Chromium sessions reached over CDP, with profiles, egress, and timeouts managed outside the agent.
  3. Orchestration layer — your queue, worker pool, and retry policy. This is the part nobody open-sources because it is specific to your workload.
  4. Observability layer — traces, screenshots, and a live viewer for the sessions that fail.

The GitHub repo handles layer one. Layers two through four are where production actually happens, and they are the layers that determine whether your agent completes tasks or burns budget. If you want to see what driving a hosted session looks like end to end, Remote control browser covers the control-plane side.

Summary

A browser use production GitHub repo gives you the agent loop. It does not give you session lifetime management, profile persistence, egress handling, or observability — and those are the things that break. Read candidate repos for how they handle browser lifecycle, not just how they prompt a model. Wire the runtime over CDP so the agent connects to a browser instead of launching one. Set a timeout on every session, assert auth state before the loop, and capture evidence on failure.

Do those four things and most of the "it works locally" problems disappear.