Doramagic Project Pack ยท Human Manual

steel-browser

๐Ÿ”ฅ Open Source Browser API for AI Agents & Apps. Steel Browser is a batteries-included browser sandbox that lets you automate the web without worrying about infrastructure.

Overview & System Architecture

Related topics: Sessions, Quick Actions & Browser Integrations, Plugin System, Chrome Extensions & Anti-Detection, Deployment, Configuration & Troubleshooting

Section Related Pages

Continue reading this section for the full explanation and source context.

Related topics: Sessions, Quick Actions & Browser Integrations, Plugin System, Chrome Extensions & Anti-Detection, Deployment, Configuration & Troubleshooting

Overview & System Architecture

Purpose & Scope

Steel is an open-source browser API designed to give AI agents and applications programmatic control over real Chrome instances without the need to build browser-automation infrastructure from scratch. The project exposes a REST surface for session lifecycle, scraping, screenshots, PDF generation, and search, while delegating browser control to Puppeteer/Chrome DevTools Protocol (CDP) under the hood Source: [README.md].

The system is delivered as a self-hostable bundle (one combined Docker image) and is also offered as a managed "Steel Cloud" service. The same API is consumed by official Node and Python SDKs (steel-sdk), and clients can attach to running sessions with Puppeteer, Playwright, or Selenium because the underlying transport is standard CDP Source: [README.md].

The repository scope deliberately covers: full browser control, persistent session state, proxy chain management, custom extension loading, request/debug logging, anti-detection (stealth plugins and fingerprint management), automatic resource cleanup, and conversion utilities for markdown/readability/screenshot/PDF output Source: [README.md]. Community issue #123 confirms that users expect deeper documentation on these feature areas, so this overview surfaces the architectural shape that underpins them.

System Components

The repository is organized as a monorepo with three independently versioned workspaces plus an extensions folder. Each package has its own package.json and runs as a distinct process in development, while the production Docker image bundles them.

ComponentPathRuntimePrimary Responsibility
API serverapi/Fastify 5 on Node โ‰ฅ22REST API, session orchestration, CDP proxy, scrape/screenshot/PDF actions
Web UIui/React 18 + Vite + RadixOperator dashboard, session debugger, recording playback
REPLrepl/Node + tsx + puppeteer-coreLocal scripting harness that connects to a live CDP endpoint
Recorder extensionapi/extensions/recorder/Chromium extension (rrweb)Captures DOM events inside the page for later replay

The API package owns the long-lived browser processes; the UI is a stateless viewer and controller; the REPL is a developer convenience; and bundled extensions are loaded into the browser at launch. The recorder extension notably pulls rrweb and @rrweb/packer to serialise page activity, which the UI replays using rrweb-player Source: [api/extensions/recorder/package.json].

Architecture & Data Flow

Steel follows a layered design: external clients hit the Fastify API, the API owns session managers that wrap Puppeteer pages, and Puppeteer talks to Chrome over a local CDP WebSocket. The WebSocket is also exposed outward so that SDKs and end-user scripts can attach Puppeteer/Playwright/Selenium to the same browser that backs the REST actions Source: [README.md].

flowchart LR
    Client[Client / SDK / REPL] -->|REST| API[Fastify API - api/]
    Client -.->|CDP WebSocket| Browser[Chrome Instance]
    API -->|Puppeteer-core 23.6.0| Browser
    API --> Schema[Zod Schemas - utils/schema.ts]
    API --> Scrape[Scrape utilities - scrape/pdfToHtml.ts, scrape/jsonToMarkdown.ts]
    API --> Cast[Page Casting - utils/casting.ts]
    API --> Filter[URL Pattern Filters - utils/requests.ts]
    UI[React UI - ui/] -->|REST + WS| API
    Browser --> Recorder[rrweb Recorder Extension]
    Recorder --> UI

Key cross-cutting concerns are implemented as shared utilities under api/src/utils/:

The REPL package is intentionally minimal โ€” it declares only puppeteer-core and tsx as runtime/dev dependencies and a single start script, confirming that it is meant to attach to an already-running API rather than spin up its own browser Source: [repl/package.json].

Technology Stack & Integration Patterns

The runtime stack is deliberately narrow. On the server side, Fastify 5 with plugins for CORS, multipart, sensible defaults, static, view, and Swagger powers the HTTP surface; [email protected] is the single browser-control dependency; and proxy-chain, http-proxy, https-proxy-agent, and socks-proxy-agent together implement the proxy-chain feature called out in the README Source: [api/package.json]. Anti-detection is delivered through [email protected] and [email protected], which are pinned to identical versions to keep the generator/injector pair in lockstep Source: [api/package.json].

The UI package is a Vite-bundled SPA that consumes a generated OpenAPI client via @hey-api/openapi-ts, renders with Radix primitives and Tailwind, and uses rrweb-player to replay recordings produced by the recorder extension Source: [ui/package.json]. This codegen-driven approach means the UI never drifts from the API surface as long as npm run generate-api is re-run after schema changes.

Configuration is environment-driven (dotenv), and the production image exposes port 3000 for the API and 9223 for the CDP endpoint. The README documents one-liner Docker, Railway, and Render deploys, plus a local docker run command that maps both ports Source: [README.md].

Known Limitations & Operational Considerations

Several architectural boundaries are visible directly from the source:

  • Single-node session affinity. Each Chrome process is bound to the API node that launched it. Community issue #144 highlights the lack of built-in cluster support and session routing across nodes; the current architecture does not provide that out of the box.
  • Fingerprint generator brittleness. Because the API pins fingerprint-generator and fingerprint-injector to the same minor version, a Chrome upgrade can break fingerprint consistency. Issues #295 and #302 both report "Failed to generate a consistent fingerprint after 10 attempts" with Chrome 146 at 1920x1080, forcing operators to set SKIP_FINGERPRINT_INJECTION as a workaround. Operators should treat the fingerprint versions as a coupled unit when planning Chrome upgrades Source: [api/package.json].
  • Local-dev runtime requirements. Issue #230 shows a ReferenceError: File is not defined when running npm run dev on Node versions missing the File global. Both api and repl workspaces declare "node": ">=22.0.0" in their engines, which is the supported floor for local development Source: [repl/package.json].
  • Security posture is operator-managed. The README describes Steel as a tool for building agents, and the project has an active coordinated vulnerability disclosure program (issue #311). Self-hosters are responsible for network exposure, proxy trust, and CSP for any custom extensions they bundle.

See Also

Source: https://github.com/steel-dev/steel-browser / Human Manual

Sessions, Quick Actions & Browser Integrations

Related topics: Overview & System Architecture, Plugin System, Chrome Extensions & Anti-Detection

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Purpose and Shape

Continue reading this section for the full explanation and source context.

Section Lifecycle Hooks

Continue reading this section for the full explanation and source context.

Section SDK Usage

Continue reading this section for the full explanation and source context.

Related topics: Overview & System Architecture, Plugin System, Chrome Extensions & Anti-Detection

Sessions, Quick Actions & Browser Integrations

Overview

Steel exposes three complementary ways to drive a Chromium instance: Sessions for stateful, long-lived browser workflows; Quick Actions (/scrape, /screenshot, /pdf) for one-shot read-only jobs; and Browser Integrations (Puppeteer, Playwright, Selenium, raw CDP) that let external automation frameworks attach to the same browser process. Together they cover the spectrum from low-level CDP control to high-level content extraction, all behind a Fastify HTTP API documented at http://localhost:3000/documentation Source: README.md:1-120.

The api package registers these capabilities as a Fastify plugin tree. The top-level routes.ts mounts the sessions and actions modules and the SDK exports in api/package.json expose the same building blocks as typed packages (./plugin, ./cdp-plugin, ./logger, ./storage, ./browser) Source: api/package.json:1-60. This layered design is what allows the official Node and Python SDKs and the bundled repl to all speak to a single browser instance.

flowchart LR
  Client["SDK / curl / Puppeteer / Playwright"] -->|HTTP| API["Fastify API<br/>(api/src/routes.ts)"]
  API --> Sessions["/v1/sessions<br/>sessions.controller.ts"]
  API --> Actions["/v1/{scrape,screenshot,pdf}<br/>actions.controller.ts"]
  API --> CDP["CDP endpoint (9223)"]
  Sessions --> Browser["Puppeteer-core<br/>Chrome Process"]
  Actions --> Browser
  CDP --> Browser
  Browser --> Repl["@steel-browser/repl<br/>(puppeteer-core)"]

Sessions: Stateful Browser Lifecycle

Purpose and Shape

The Sessions module is the centerpiece for stateful automation. It creates, releases, resets, and releases browser contexts, and persists cookies, localStorage, sessionStorage, and IndexedDB so workflows can be paused and resumed. The schema is defined in sessions.schema.ts and exposed as REST endpoints in sessions.routes.ts Source: api/src/modules/sessions/sessions.routes.ts:1-80.

SessionData in the context utilities formalizes what is captured per origin:

Storage DomainCDP Domain UsedNotes
localStorageDOMStorage.getDOMStorageItemsKey/value per origin
sessionStorageDOMStorage.getDOMStorageItemsTab-scoped key/value
indexedDBIndexedDB queriesDatabase + object store records
CookiesNetwork.getCookiesRe-injected on relaunch

Source: api/src/utils/context.ts:1-60.

Lifecycle Hooks

Steel ships a plugin lifecycle that includes the most recent additions from v0.5.3-beta: onSessionStart, onBeforeSessionEnd, and onAfterSessionEnd. These hooks let plugin authors react when a session is created, about to close, or has just released its resources, complementing the earlier onBrowserReady hook (which now also supports promises) Source: Release v0.5.3-beta, Release v0.5.0-beta.

A typical session flow is:

  1. POST /v1/sessions with options such as proxyUrl, userDataDir, extensionIds, isSelenium, or fullscreen Source: README.md:90-130.
  2. The controller launches Puppeteer, applies the fingerprint and extension, and returns { id, wsUrl, debuggerUrl, viewerUrl }.
  3. Downstream calls (e.g. POST /v1/sessions/:id/context or DELETE /v1/sessions/:id/release) round-trip through the controller and invoke the relevant plugin hooks.
  4. Resource cleanup is consolidated; the v0.4.5-beta release explicitly fixed default download behavior and error flows for session teardown Source: Release v0.4.5-beta.

SDK Usage

The Node and Python SDKs are thin wrappers around these routes. They expose a typed client.sessions.create({ ... }) and client.sessions.release(id) API and allow swapping the cloud endpoint via the baseURL / base_url option for self-hosted deployments Source: README.md:140-180.

Quick Actions: One-Shot Extraction

Quick Actions are read-only HTTP endpoints that boot a transient session, perform a single action, and return the result. They are documented as ideal for "simple, read-only, on-demand jobs" and are mounted under /v1 Source: README.md:150-200.

The three actions currently supported:

EndpointBodyResult
POST /v1/scrape{ url, delay, ... }Cleaned HTML/markdown via Defuddle
POST /v1/screenshot{ url, fullPage, ... }PNG image of the page
POST /v1/pdf{ url, ... }Rendered PDF (parses back to HTML on retrieval)

Source: README.md:150-200, api/src/utils/scrape/readability.ts:1-30.

Content Extraction Internals

getDefuddleContent runs Defuddle once on the raw HTML and inspects the result. If the result is "thin" (no markdown or fewer than 50 words and no extractor type), a second pass runs with aggressive stripping (<script>, <style>, <noscript> removed) and a relaxed selector set. The richer of the two passes wins, and its content/contentMarkdown/wordCount fields replace the originals Source: api/src/utils/scrape/readability.ts:1-60.

PDFs follow a parallel path: the pdfToHtml.ts utility uses mupdf to walk sections, collect links, and wrap the result in an HTML envelope with metadata (title, info:ModDate). The scrape action can therefore return either HTML scraped from a live page or HTML reconstructed from a PDF Source: api/src/utils/scrape/pdfToHtml.ts:1-40, api/package.json:30-80.

Browser Integrations: CDP, Puppeteer, Playwright, Selenium

CDP and the bundled REPL

Steel exposes a WebSocket CDP endpoint (default port 9223) that is compatible with any CDP client. The bundled repl package wires this endpoint to puppeteer-core so developers can drive a running Steel instance interactively:

cd repl
npm start   # runs src/script.ts with tsx

Source: repl/README.md:1-15, repl/package.json:1-20. The repl intentionally depends on puppeteer-core (not full Puppeteer) because the browser is launched by the API process.

Casting, Navigation, and Context Tools

api/src/utils/casting.ts provides low-level helpers (navigatePage, getPageTitle, getPageFavicon) used by casting/CDP plugins to map incoming events to puppeteer-core calls and to normalize URLs before page.goto. api/src/utils/context.ts complements these by extracting storage state from every visited origin so it can be restored on the next launch Source: api/src/utils/casting.ts:1-50, api/src/utils/context.ts:1-60.

First-Party Automation Frameworks

Puppeteer and Playwright can be pointed at Steel by using the session's wsUrl (or debuggerUrl) as the browserWSEndpoint / connectOptions.wsEndpoint. The README links to dedicated guides for Puppeteer, Playwright (Node and Python), and Selenium integrations Source: README.md:160-200. For Selenium, Steel offers a drop-in compatible mode activated with isSelenium: true when creating a session, exposing a WebDriver-compatible endpoint Source: README.md:120-150.

The recorder extension lives under api/extensions/recorder/ and uses rrweb + @rrweb/packer to capture page activity for replay in the UI's rrweb-player Source: api/extensions/recorder/package.json:1-15, ui/package.json:10-50.

Common Failure Modes & Troubleshooting

Several community-reported issues map directly onto this surface area:

  • Fingerprint generation failures โ€” Self-hosted steel-browser-api v0.5.3 with [email protected] can fail to generate a consistent fingerprint on Chrome 146 at fixed 1920x1080. The temporary workaround is to set SKIP_FINGERPRINT_INJECTION=1; the upstream issue is tracked in #302 and #295 Source: issue #302, issue #295.
  • npm run dev boot failure โ€” A ReferenceError: File is not defined inside undici when running the API locally; the typical resolution is to run on Node 22+ (which is also enforced via engines in api/package.json) Source: issue #230, api/package.json:1-30.
  • Feature gaps โ€” Community requests (#123, #144) highlight the desire for more documentation on advanced features and for cluster-level request routing to the node hosting a given session. The README confirms that all session-aware operations today are scoped to a single API instance Source: issue #123, issue #144.

When in doubt, the Swagger UI at /documentation and the Scalar reference at /scalar reflect the live schema defined by the modules cited above Source: api/package.json:30-60.

See Also

Source: https://github.com/steel-dev/steel-browser / Human Manual

Plugin System, Chrome Extensions & Anti-Detection

Related topics: Overview & System Architecture, Sessions, Quick Actions & Browser Integrations, Deployment, Configuration & Troubleshooting

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Plugin Lifecycle Hooks

Continue reading this section for the full explanation and source context.

Section Known Anti-Detection Failure Modes

Continue reading this section for the full explanation and source context.

Related topics: Overview & System Architecture, Sessions, Quick Actions & Browser Integrations, Deployment, Configuration & Troubleshooting

Plugin System, Chrome Extensions & Anti-Detection

Overview

Steel Browser is an open-source browser API that combines three extensibility surfaces into a single stack:

  1. A Node/TypeScript plugin system that lets developers hook into the browser and CDP lifecycle.
  2. A Chrome extension loader that can ship custom extensions (e.g., the bundled steel-recording-extension) into the launched Chrome instance.
  3. An anti-detection layer built around fingerprint-generator and fingerprint-injector, paired with stealth helpers to reduce automated-traffic signals.

The README summarises this as "Anti-Detection: Includes stealth plugins and fingerprint management" and "Extension Support: Load custom Chrome extensions for enhanced functionality" (README.md:55-63).

The API package exposes these surfaces as named subpath exports so they can be consumed independently of the running server (api/package.json:9-35):

SubpathPurpose
@steel-browser/api/pluginPublic plugin authoring entrypoint (steel-browser-plugin.ts)
@steel-browser/api/cdp-pluginBase class for CDP-layer plugins (services/cdp/plugins/core/base-plugin.ts)
@steel-browser/api/loggerBrowser-side logger plugin (plugins/logging/browser-logger)
@steel-browser/api/storageLog storage interface used by instrumentation plugins
@steel-browser/api/browserBrowser type definitions

Plugin System Architecture

The plugin stack is split into two layers:

  • CDP plugins โ€” run inside the Node process, attached to Chrome DevTools Protocol sessions via BaseCDPPlugin. The class contract and manager orchestration live under api/src/services/cdp/plugins/core/ (api/package.json:13-19).
  • Browser-context plugins โ€” ship JavaScript that runs inside the page via Puppeteer's evaluateOnNewDocument. The bundled installMouseHelper utility in api/src/utils/browser.ts is a representative example: it injects a cursor overlay guarded by a frame check so it only runs on top-level windows (api/src/utils/browser.ts:38-89).

A typical flow when a session starts looks like the diagram below.

flowchart LR
    Client -->|HTTP /v1/sessions| API[Fastify API]
    API --> PM[PluginManager]
    PM -->|attach| CDP[CDP Plugins<br/>BaseCDPPlugin]
    PM -->|launch hook| Browser[Browser Plugins<br/>browser-session.ts / browser.ts]
    Browser -->|evaluateOnNewDocument| Page[Target Page]
    PM -->|load flags| FG[fingerprint-generator<br/>fingerprint-injector]
    FG --> Page

Plugin Lifecycle Hooks

The lifecycle is event-driven. Recent releases have stabilised the hook contract:

  • v0.5.3-beta introduced onSessionStart, onBeforeSessionEnd, and onAfterSessionEnd as first-class plugin hooks (Release v0.5.3-beta).
  • v0.5.0-beta allowed onBrowserReady to return a Promise, letting plugins await async setup before the browser is handed to the caller (Release v0.5.0-beta).
  • v0.5.2-beta added the ability for plugins to override the disconnect handler (Release v0.5.2-beta).
  • v0.4.3-beta improved plugin launch hook timing and added fingerprint override support (Release v0.4.3-beta).

Plugins authored against this contract implement BaseCDPPlugin from services/cdp/plugins/core/base-plugin.ts and are registered through PluginManager in services/cdp/plugins/core/plugin-manager.ts (api/src/services/cdp/plugins/core/base-plugin.ts).

Chrome Extension Support

Steel can load arbitrary Chrome extensions into the launched Chrome instance, which is essential for capabilities like DOM recording and content scripts. The repository ships one reference extension:

Extensions are bundled with Webpack and shipped at runtime alongside the API container. The REPL package (@steel-browser/repl) demonstrates the consumption side: it uses puppeteer-core to connect to the CDP WebSocket exposed by the API and drive the browser programmatically (repl/README.md:1-15, repl/package.json:1-23). The same REPL entrypoint can be reused by any extension-driven workflow that needs CDP-level access.

Anti-Detection: Fingerprinting & Stealth

Anti-detection in Steel rests on two pinned dependencies:

PackagePinned versionRole
fingerprint-generator2.1.82Generates consistent browser fingerprints (UA, screen, locale, hardware)
fingerprint-injector2.1.82Applies the generated fingerprint to every launched context

Both are listed in api/package.json as runtime dependencies (api/package.json:73-110). The fingerprint pipeline is invoked from the launch path and is overridable by plugins โ€” see the v0.4.3-beta fingerprint override support note in Release v0.4.3-beta.

Known Anti-Detection Failure Modes

The community has surfaced two related bugs that operators should be aware of when self-hosting:

  • Issue #295 โ€” Failed to generate a consistent fingerprint after 10 attempts. Reported against steel-browser and steel-browser-api images; the browser never launches and the container becomes unhealthy.
  • Issue #302 โ€” Same root cause but triggered specifically by Chrome 146 at a fixed 1920x1080 viewport, forcing operators to set SKIP_FINGERPRINT_INJECTION as a workaround.

The mitigation pattern documented in those threads is to disable fingerprint injection via the SKIP_FINGERPRINT_INJECTION environment variable when the pinned [email protected] cannot produce a consistent profile for the requested viewport/UA combination.

Security note: A coordinated vulnerability disclosure is currently open against the project (Issue #311) via VulnCheck. Operators tracking anti-detection or extension behaviour should watch that issue for remediation guidance.

Failure Modes & Operational Tips

SymptomLikely CauseMitigation
ReferenceError: File is not defined on npm run dev (Issue #230)Node version older than what undici expects File to be globally definedUse Node โ‰ฅ 22 (matches engines in repl/package.json:18-22)
Failed to generate a consistent fingerprint after 10 attempts (Issue #295)[email protected] cannot match the requested UA/viewport combinationSet SKIP_FINGERPRINT_INJECTION=1 or adjust the requested viewport (Issue #302)
Extension not visible in launched ChromeExtension not built or not copied into the container imageRun npm run build inside api/extensions/recorder/ (api/extensions/recorder/package.json:10-12)
Custom Chrome binary ignoredCHROME_EXECUTABLE_PATH set to a path that does not existgetChromeExecutablePath() only warns and falls back to /usr/bin/chromium (api/src/utils/browser.ts:3-22)

See Also

  • README.md โ€” high-level feature overview and deployment options.
  • Release v0.5.3-beta โ€” most recent plugin hook additions.
  • Release v0.4.3-beta โ€” plugin launch hook timing and fingerprint override support.
  • Issue #144 โ€” community request for cluster/session-affinity routing, relevant when scaling plugin state across nodes.

Source: https://github.com/steel-dev/steel-browser / Human Manual

Deployment, Configuration & Troubleshooting

Related topics: Overview & System Architecture, Sessions, Quick Actions & Browser Integrations, Plugin System, Chrome Extensions & Anti-Detection

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Quick Deploy (managed / one-click)

Continue reading this section for the full explanation and source context.

Section Docker (self-hosted)

Continue reading this section for the full explanation and source context.

Section Local development

Continue reading this section for the full explanation and source context.

Related topics: Overview & System Architecture, Sessions, Quick Actions & Browser Integrations, Plugin System, Chrome Extensions & Anti-Detection

Deployment, Configuration & Troubleshooting

This page covers the operational side of the steel-browser project: how to run the API, the UI, and the REPL; how to tune the platform through environment variables; and how to recover from the most common failure modes reported by the community.

Overview

steel-browser is shipped as a multi-package workspace. Three services make up a working installation:

  • API โ€“ a Fastify-based Node service that manages Chrome sessions, proxies CDP traffic, and exposes the REST + WebSocket surface used by the Python and Node SDKs. Source: api/package.json
  • UI โ€“ a Vite + React debugging console that lists live sessions, replays recorded sessions via rrweb-player, and provides a Swagger / Scalar reference browser. Source: ui/package.json
  • REPL โ€“ a small Puppeteer-based script that connects over CDP for adโ€‘hoc scripting. Source: repl/package.json

The default public ports are 3000 for the API and 9223 for the CDP endpoint, with the UI dev server bound to 5173 by default. Source: README.md

flowchart LR
  Client[SDK / curl / Puppeteer] -->|HTTPS :3000| API[Fastify API]
  Client -->|WSS :9223| CDP[Chrome DevTools Protocol]
  API --> Browser[Headless Chrome]
  UI[Vite UI :5173] -->|OpenAPI proxy| API
  REPL[repl/src/script.ts] -->|WS :9223| CDP

Deployment Options

Quick Deploy (managed / one-click)

The README documents three hosted paths so a working instance can be brought up without a local toolchain:

MethodSurfaceSource
GHCR combined image (ghcr.io/steel-dev/steel-browser)API + UI in one containerREADME.md
Railway one-clickAPI + UI on RailwayREADME.md
Render one-clickAPI + UI on RenderREADME.md

For Steel Cloud, the same steel-sdk is reused against a managed endpoint by changing baseURL (Node) or base_url (Python). Source: README.md

Docker (self-hosted)

A minimal self-hosted run uses the prebuilt image and exposes both ports:

docker run -p 3000:3000 -p 9223:9223 ghcr.io/steel-dev/steel-browser

The image's entrypoint, api/entrypoint.sh, bootstraps the API process and prepares the recorder extension (which is built from api/extensions/recorder/package.json via npm run prepare:recorder). Source: api/package.json

Local development

Each package has its own scripts. The API supports hot reload through tsx watch, the UI through Vite, and the REPL through tsx:

# API
cd api && npm run dev          # tsx watch src/index.ts
# UI
cd ui  && npm run dev          # vite --host 0.0.0.0
# REPL
cd repl && npm start           # tsx ./src/script.ts

Source: api/package.json, ui/package.json, repl/README.md

Configuration

Configuration is exclusively environment-driven, parsed in api/src/config.ts using dotenv. The full schema lives in api/.env.example and the root .env.example.

Variable (selected)DefaultPurpose
PORT3000API HTTP port. Source: api/src/config.ts
CDP_PORT9223Chrome DevTools Protocol WebSocket port. Source: README.md
STEEL_API_KEY_empty_Bearer token for incoming REST/WS requests. Source: api/.env.example
PROXY_URL_empty_Upstream proxy chained into the browser via proxy-chain. Source: api/package.json
SKIP_FINGERPRINT_INJECTIONfalseDisables stealth/fingerprinting at launch. Source: api/.env.example
OPTIMIZE_BANDWIDTHfalseReduces traffic between API and browser (added in v0.4.2). Source: GitHub release v0.4.2-beta
SCRAPE_EVAL_HEAVY_unset_Enables heavier evaluation test path. Source: api/package.json

Logging uses pino and pino-pretty and is configured through the same file. Source: api/package.json

Troubleshooting

The following failure modes appear repeatedly in the issue tracker and are directly addressable from configuration.

Browser fails to launch with fingerprint errors

Self-hosted containers on Chrome 146 at a fixed 1920x1080 viewport throw Fingerprint error during generation: Failed to generate a consistent fingerprint after 10 attempts and the container becomes unhealthy. The root cause is a mismatch between the pinned [email protected] and the new Chrome version. Two workarounds are used in the wild:

  • Set SKIP_FINGERPRINT_INJECTION=true to bypass stealth and restore startup. Source: Issue #302, Issue #295
  • Upgrade the fingerprint-generator / fingerprint-injector pair to a version that supports the new UA string, then rebuild the image.

`ReferenceError: File is not defined` during `npm run dev`

undici (a transitive dependency) references the File Web API, which is missing in Node < 18. Both api/package.json and repl/package.json declare "engines": { "node": ">=22.0.0" } (the API itself requires modern Node for the dev experience). Source: Issue #230. Use Node 20+ LTS (22+ recommended) and a clean node_modules install.

Recorder extension missing

The session recorder relies on a webpack build of the rrweb extension that is not produced during npm install. It is built on demand by npm run prepare:recorder (called automatically by npm run dev). Source: api/package.json. In Docker, api/entrypoint.sh performs the same step during image build; a missing recorder usually means the build step was skipped or its output pruned.

Session affinity and clustering

There is no built-in cross-node session routing: a session ID is valid only on the node that owns the Chrome process behind CDP_PORT. Multi-node deployments must front the cluster with a sticky router keyed on the session id returned by /v1/sessions. Source: Issue #144.

Security disclosures

The project runs a coordinated vulnerability disclosure program. Report suspected issues privately before opening a public ticket. Source: Issue #311.

Diagnostics checklist

  1. GET /health and the Swagger UI at /documentation to confirm the API is up. Source: README.md
  2. Inspect pino logs (or docker logs <container>) for fingerprint, proxy, and CDP errors.
  3. From the REPL, connect directly to ws://host:9223 to isolate API problems from browser problems. Source: repl/README.md
  4. Re-run npm test (Vitest) inside api/ to catch regressions introduced by configuration changes. Source: api/package.json

See Also

  • README.md โ€“ high-level features, deploy buttons, and SDK pointers
  • api/src/config.ts โ€“ authoritative list of environment variables
  • api/.env.example โ€“ documented defaults
  • repl/README.md โ€“ CDP debugging scripts
  • GitHub releases โ€“ changelog for flags such as OPTIMIZE_BANDWIDTH and fullscreen

Source: https://github.com/steel-dev/steel-browser / Human Manual

Doramagic Pitfall Log

Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.

high Installation risk requires verification

May increase setup, validation, or first-run risk for the user.

high Installation risk requires verification

May increase setup, validation, or first-run risk for the user.

high Installation risk requires verification

May increase setup, validation, or first-run risk for the user.

medium Installation risk requires verification

May increase setup, validation, or first-run risk for the user.

Doramagic Pitfall Log

Found 11 structured pitfall item(s), including 3 high/blocking item(s). Top priority: Installation risk - Installation risk requires verification.

1. Installation risk: Installation risk requires verification

  • Severity: high
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/steel-dev/steel-browser/issues/302

2. Installation risk: Installation risk requires verification

  • Severity: high
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/steel-dev/steel-browser/issues/295

3. Installation risk: Installation risk requires verification

  • Severity: high
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/steel-dev/steel-browser/issues/230

4. Installation risk: Installation risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: identity.distribution | https://github.com/steel-dev/steel-browser

5. Capability evidence risk: Capability evidence risk requires verification

  • Severity: medium
  • Finding: README/documentation is current enough for a first validation pass.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: capability.assumptions | https://github.com/steel-dev/steel-browser

6. Maintenance risk: Maintenance risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | https://github.com/steel-dev/steel-browser

7. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: no_demo
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: downstream_validation.risk_items | https://github.com/steel-dev/steel-browser

8. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: no_demo
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: risks.scoring_risks | https://github.com/steel-dev/steel-browser

9. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: community_evidence:github | https://github.com/steel-dev/steel-browser/issues/311

10. Maintenance risk: Maintenance risk requires verification

  • Severity: low
  • Finding: issue_or_pr_quality=unknownใ€‚
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | https://github.com/steel-dev/steel-browser

11. Maintenance risk: Maintenance risk requires verification

  • Severity: low
  • Finding: release_recency=unknownใ€‚
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | https://github.com/steel-dev/steel-browser

Source: Doramagic discovery, validation, and Project Pack records

Community Discussion Evidence

These external discussion links are review inputs, not standalone proof that the project is production-ready.

Sources 12

Count of project-level external discussion links exposed on this manual page.

Use Review before install

Open the linked issues or discussions before treating the pack as ready for your environment.

Community Discussion Evidence

Doramagic exposes project-level community discussion separately from official documentation. Review these links before using steel-browser with real data or production workflows.

Source: Project Pack community evidence and pitfall evidence