Skip to content
fastbrowsefastbrowse

docs

Use it from JavaScript

Install the TypeScript SDK, run a task, and keep secrets, authorization and output validation in your process.

fastbrowse.ai·all docs·source at the pinned commit·Raw Markdown·llms.txt

npm install fastbrowse gives a Node program the same agent, with no Python and no uv on the machine. The package is a TypeScript SDK with no dependencies. With it npm installs one of five packages that hold the agent as a native binary, the one for your platform: @fastbrowse/darwin-arm64, darwin-x64, linux-arm64, linux-x64 or win32-x64. No install script runs and nothing is downloaded on first use, so it installs under pnpm and bun with scripts blocked, and it starts offline. It needs Node.js 20 or newer. The npm packages carry the PyPI package's version and are published by the same tag, starting with the release after 0.5.18.

The binary brings no browser. It finds local Chrome, starts a Browser Use Cloud browser, or drives one already running, as the command line does. It reads the same keys from the environment of your process (OPENROUTER_API_KEY, and BROWSER_USE_API_KEY for a cloud browser); env in Fastbrowse.start adds to them.

npm install fastbrowse zod
export OPENROUTER_API_KEY=...
import { Fastbrowse } from 'fastbrowse';
import { z } from 'zod';

const Release = z.object({ package: z.string(), version: z.string() });

const fb = await Fastbrowse.start({ local: true });
try {
  const result = await fb.run('Find the httpx package and report its name and latest released version.', {
    start: 'https://pypi.org/',
    output: Release,
    limits: { maxDollars: 0.1 },
    onEvent: event => {
      if (event.type === 'step') console.error(event.step.operation, event.step.target);
    },
    signal: AbortSignal.timeout(120_000),
  });
  console.log(result.status, result.answer);
  if (result.status === 'complete') console.log(result.output.package, result.output.version);
  for (const evidence of result.evidence) console.log(`  "${evidence.quote}" from ${evidence.url}`);
} finally {
  await fb.close();
}

Fastbrowse.start starts one fastbrowse process and run sends it a task. The process serves one run at a time: a second run while one is active rejects with the busy error, and a program that wants runs side by side starts more instances. close() shuts the process down and waits for it. The process also exits when yours does, however yours ended.

run resolves with the result whatever status the run ended in, so needs_login or stuck is read from status and is not an exception. It rejects when no run took place or none finished: with RpcError when the server refuses the request before a browser opens (a bad option, a missing key, a busy server), with AbortError when signal stopped the run, and with ProcessExitedError when the process is gone. A run that fails after it has started resolves with status error.

The result is the RunResult the Python library returns, with the same statuses, citations and cost lines. Its fields keep their Python names, such as final_url, since the types are generated from the Python models; the options are camelCase. The structured data is in data, as in Python. The SDK adds output: with a Zod (4.2 or newer) or ArkType schema, or a Valibot schema wrapped by @valibot/to-json-schema, output is data after the schema's own validation and transforms, and has the schema's output type. Data the schema refuses rejects with OutputValidationError, which carries the result. A JSON Schema object is accepted too; output is then data, typed unknown.

What a run can fill today is narrower than what a schema can say. The server accepts nested objects, arrays, enum, const and optional values, and refuses any other keyword by name before a browser opens. A run fills a flat object of required string, number, integer and boolean fields, as the example has. With any other field the run ends unverified with no data.

The callbacks that keep credentials and the last word in your code cross the process boundary:

await fb.run('Log in as standard_user with the saved password and add the backpack to the cart.', {
  start: 'https://www.saucedemo.com/',
  authorization: { irreversibleActions: true },
  secrets: {
    refs: [{ name: 'password', origins: ['https://www.saucedemo.com'] }],
    resolve: name => vault.get(name),
  },
  until: url => url.endsWith('/cart.html'),
});

secrets.resolve is called each time a value is typed and never for an origin its ref does not cover, so the value leaves your vault at that moment and a one-time code is fresh. until gets the address the run ended on, and anything but true keeps the run from complete. onFrame receives JPEG frames of the active tab; without it no frame is sent. A callback that throws ends the run with status error. The other options are the command line's: inputs, attachments as bytes, downloads, record, and the browser choices chrome, cloudProfile, cdpUrl, cdpPort, attach, targetMatch and proxyCountry, which Fastbrowse.start also takes as defaults for every run. A run passes null for one of them to go without that default.

There is no binary for Alpine or another musl system, and none for a platform outside the five. There Fastbrowse.start rejects with an error that names the platform, and a binary of your own is named with binaryPath or FASTBROWSE_BINARY. The macOS binaries carry an ad-hoc signature and are not notarized, which a Mac that allows programs only by the team that signed them refuses. The Windows binary is not signed. Bun and Deno are untested.

Use fastbrowse with your agent

Install the fastbrowse skill to delegate website tasks from an agent that supports Agent Skills. It uses the MCP tool when connected, or the CLI, and preserves the task's citations, status, authorization, and budget. The guide covers agent selection, configuration, and example prompts for Codex and Claude Code. Agents without skill support can use the CLI or MCP server directly.

Run fastbrowse through Nebula

Nebula embeds fastbrowse in its agent harness, with browser steps, results and permitted vault logins. Use Bitwarden or 1Password through Nebula with credentials scoped to authorized websites.