3000 和 9223 端口默认无鉴权,不要暴露到公网;Mac Silicon 用 docker compose 时需加 DOCKER_DEFAULT_PLATFORM=linux/arm64;用 Node.js 方式运行需自行安装 Chrome 并放在 README 列出的默认路径。
steel-browser
steel-devApache-2.0活跃维护开箱即用的浏览器沙箱 API,让 AI Agent 和应用直接调用无头浏览器完成网页自动化,省去自建基础设施的麻烦。
🔥 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.
docker run -p 3000:3000 -p 9223:9223 ghcr.io/steel-dev/steel-browserREADME 未说明显存或 GPU 要求;本地运行需已安装 Chrome,或通过 CHROME_EXECUTABLE_PATH 指定可执行文件路径。
开源浏览器 API,为 AI 代理和自动化应用托管会话、页面与 Chrome 进程
开箱即用的浏览器沙箱 API,让 AI Agent 和应用直接调用无头浏览器完成网页自动化,省去自建基础设施的麻烦。
核心能力
- 用 Puppeteer 和 CDP 完全控制 Chrome 实例
- 跨请求保持浏览器状态、Cookie 与本地存储
- 内置代理链管理实现 IP 轮换
- 支持加载自定义 Chrome 扩展
- 提供页面转 Markdown、截图、PDF 等快捷接口
容易踩的坑
- v0.5.5-betaRelease v0.5.5-beta最新正式版2026-10-31 · 2026-10-31 22:53 UTC
Improvements
093760: feat(docker): run API image under tini init (#386) (@Gourav224)cfedcb: feat: commands api (#384) (@junhsss)f48b02: feat: overhaul the ui and live view streaming (#402) (@junhsss)
Bug Fixes
2b4112: fix(context): stop /context polling from slowing down the browser (#356) (@fukouda)911d14: fix(sessions): settle proxy byte counters before ending a session (#361) (@fukouda)04f691: fix(cdp): bound storage extraction and skip crashed renderers (#362) (@fukouda)dacea7: fix(api): align mobile device emulation signals (#366) (@danew)e5902f: fix(cdp): eliminate dedicated worker network capture race (#327) (@danew)1131a0: fix(cdp): log blocked requests at debug instead of info (#374) (@fukouda)d8a4a7: fix(cdp): keep lifecycle hooks bound to the outgoing browser (#376) (@danew)807bf2: fix(deps): bump @fastify/static, defuddle, file-type and vitest for security advisories (#377) (@fukouda)8362bb: fix(api): handle PDF URLs in screenshot/pdf and harden action page handling (#383) (@junhsss)e41160: fix(cdp): keep mobile emulation overrides alive (#382) (@junhsss)099466: fix(cdp): enable request interception conditionally (#387) (@starboy-3)7f1bd4: fix(ci): stop release and welcome workflows from failing (#391) (@junhsss)aca33a: fix(docker): block file:// URLs with a Chrome policy (#390) (@junhsss)79d601: fix(docker): bump Node to 22.23.4 (CVE-2026-111497) (#392) (@mahfuz-rahman007)5befc1: fix(api): cleanup session when casting target page is not found (#388) (#389) (@kaiizer777)582fdc: fix(files): send the real file name in Content-Disposition (#372) (@RaphaelFakhri)0d4bae: fix(cdp): match blocked hosts case-insensitively and with a trailing root dot (#371) (@RaphaelFakhri)3cca16: fix(proxy): settle byte counters before close() resolves (#394) (@junhsss)545fe5: fix: serialize brow
- v0.5.4-betaRelease v0.5.4-beta2026-08-25 · 2026-08-25 19:41 UTC
查看更新说明
Improvements
3b2335: feat: update chrome browser support for 146 + resolve extension installtion (#292) (@jagadeshjai)fc75fc: feat: log browser interactions (#281) (@junhsss)23fdf8: feat: migrate to mupdf (#304) (@junhsss)c80bce: feat: overhaul markdown conversion (#305) (@junhsss)746f07: feat(sessions): add caCertificates support (#310) (@grahaml)42b785: feat: add opt-in worker network instrumentation (#319) (@danew)
Bug Fixes
f72191: fix: respect skip fingerprint injection config + refactor device metrics override (#306) (@jagadeshjai)aece0a: fix(cdp): always validate timezone regardless of skipFingerprintInjection (#309) (@jagadeshjai)5f02cf: fix(cdp): fall back to relaxed fingerprint constraints instead of hard-failing (#315) (@zenprocess)5a26b9: fix(logs): prevent stack overflow flushing large DuckDB write buffers (#316) (@grahaml)1482bc: fix(cdp): capture nested scroll interactions (#323) (@danew)5880b4: fix(cdp): capture network requests from dedicated web workers (#325) (@danew)fd60dd: fix(files): rebuild dirty session archives (#349) (@grahaml)
Housekeeping
c0f226: chore: avoid modifying request headers, as it's no longer useful (#321) (@jagadeshjai)3fe241: refactor(cdp): improve error handling for closed targets and contexts (#351) (@fukouda)

Come Hang Out
- v0.5.3-betaRelease v0.5.3-beta2026-04-24 · 2026-04-24 19:39 UTC
查看更新说明
Improvements
8ccf2d: feat: add onSessionStart/onBeforeSessionEnd/onAfterSessionEnd plugin hooks (#275) (@jagadeshjai)db9daa: feat: add |fullscreen| option to open the browser in fullscreen mode (#290) (@jagadeshjai)
Bug Fixes
c1a55e: fix: avoid global Node reference in table plugin (#265) (@junhsss)221be4: fix: pass deviceConfig (#272) (@junhsss)4c7822: fix: always run session end hooks on all shutdown paths (#277) (@jagadeshjai)9bc3eb: fix: wrap live session script in IIFE to avoid global scope collisions (#273) (@majiayu000)dc585b: fix: guard onBrowserReady against concurrent shutdown (#274) (@junhsss)
Housekeeping
e541ba: chore: added typed browser extra and proxy factory interfaces (#288) (@danew)d6b15d: refactor(file-service): improve file archiving concurrency (#291) (@fukouda)

Come Hang Out
- v0.5.2-betaRelease v0.5.2-beta2026-03-15 · 2026-03-15 21:49 UTC
查看更新说明
Improvements
e9ec37: feat: allow disconnect handler override (#233) (@junhsss)ed8178: feat: Add search action (#231) (@aspectrr)861029: feat: optimise Steel browser performance (#239) (@danew)27af93: feat: add disable sandbox env var override (#260) (@danew)f36730: feat: migrate from page request events to Chrome's Network domain (#262) (@danew)
Bug Fixes
c053ee: fix: resolve and optimize timezone fetching (#234) (@jagadeshjai)1f5ec4: fix: files cleanup is more granular + home dir (#236) (@fukouda)9d99e8: fix: disable session crashed bubble (#238) (@danew)592c2b: fix: handle undefined error access (#237) (@junhsss)70da1e: fix: change default files dir in non dev envs (#244) (@danew)cf6cdf: fix: circular reference stack overflow in event storage (#251) (@danew)733cd7: fix: use minimal Logger interface to avoid pino v9/v10 type conflicts (#259) (@danew)
Documentation
a5d2cc: docs: update README.md (#248) (@hussufo)d74478: docs: fix broken documentation guide URLs in README (#255) (@Ray0907)
Housekeeping
d5efd1: chore: add a few more static chrome args for headful sessions (#232) (@danew)86ff52: perf: deduplicate URL parsing in request handler (#253) (@Ray0907)6e0ea9: perf: pre-compile URL pattern regexes at session start (#252) (@Ray0907)

Come Hang Out
- v0.5.1-betaRelease v0.5.1-beta2025-11-19 · 2025-11-19 08:53 UTC
查看更新说明
Improvements
a10637: feat: Scrape PDF Parsing (#227) (@aspectrr)b098af: feat: add logic to enable/disable cdp service (#219) (@danew)
Bug Fixes
8675b4: fix: Fix Release Script (#221) (@aspectrr)2dac49: fix: Update render.yaml deployment and readme (#220) (@aspectrr)
Housekeeping
c9f49e: chore: package bump + conditional mouse paint (#229) (@fukouda)

Come Hang Out
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
✨ Highlights
Steel.dev is an open-source browser API that makes it easy to build AI apps and agents that interact with the web. Instead of building automation infrastructure from scratch, you can focus on your AI application while Steel handles the complexity.
Under the hood, it manages sessions, pages, and browser processes, allowing you to perform complex browsing tasks programmatically without any of the headaches:
- Full Browser Control: Uses Puppeteer and CDP for complete control over Chrome instances -- allowing you to connect using Puppeteer, Playwright, or Selenium.
- Session Management: Maintains browser state, cookies, and local storage across requests
- Proxy Support: Built-in proxy chain management for IP rotation
- Extension Support: Load custom Chrome extensions for enhanced functionality
- Debugging Tools: Built-in request logging and a UI to view/debug sessions with
- Anti-Detection: Includes stealth plugins and fingerprint management
- Resource Management: Automatic cleanup and browser lifecycle management
- Browser Tools: Exposes APIs to quick convert pages to markdown, readability, screenshots, or PDFs.
For detailed API documentation and examples, check out our API reference or explore the Swagger UI directly at http://0.0.0.0:3000/documentation.
Steel is in public beta and evolving every day. Your suggestions, ideas, and reported bugs help us immensely. Do not hesitate to join in the conversation on Discord or raise a GitHub issue. We read everything, respond to most, and love you.
If you love open-source, AI, and dev tools, we're hiring across the stack!
Make sure to give us a star ⭐
🛠️ Getting Started
The easiest way to get started with Steel is by creating a Steel Cloud account. Otherwise, you can deploy this Steel browser instance to a cloud provider or run it locally.
⚡ Quick Deploy
If you're looking to deploy to a cloud provider, we've got you covered.
| Deployment methods | Link |
|---|---|
| Pre-built Docker Image (combined API + UI) | |
| 1-click deploy to Railway | |
| 1-click deploy to Render |
💻 Running Locally
Docker
The simplest way to deploy/run a Steel browser instance locally is to run the pre-built Docker image:
# Pull and run the Docker image
docker run -p 3000:3000 -p 9223:9223 ghcr.io/steel-dev/steel-browser
[!WARNING] Ports 3000 and 9223 have no authentication. Don't expose them to the public internet or other untrusted networks. See SECURITY.md.
This will start the Steel browser server on port 3000 (http://localhost:3000) and the UI at http://localhost:3000/ui. The 9223 port is used for the console debugger.
You can now create sessions, scrape pages, take screenshots, and more. Jump to the Usage section for some quick examples on how you can do that.
Alternatively, you can run the API and UI separately with docker compose:
docker compose up
For Mac Silicon users, you will need to pass this env flag to the Docker compose command to run the images on the correct platform:
DOCKER_DEFAULT_PLATFORM=linux/arm64 docker compose up
Quickstart for Contributors
When developing locally, you will need to run the docker-compose.dev.yml file instead of the default docker-compose.yml file so that your local changes are reflected. Doing this will build the Docker images from the api and ui directories and run the server and UI on port 3000 and 5173 respectively.
docker compose -f docker-compose.dev.yml up
You will also need to run it with --build to ensure the Docker images are re-built every time you make changes:
docker compose -f docker-compose.dev.yml up --build
If you run on a custom host, copy .env.example to .env and set DOMAIN and CDP_DOMAIN to your host. Docker Compose reads the .env file automatically.
Node.js
Alternatively, if you have Node.js and Chrome installed, you can run both the server and the UI directly:
npm install
npm run dev
This will also start the Steel server on port 3000 and the UI on port 5173.
Make sure you have the Chrome executable installed and in one of these paths:
-
Linux:
/usr/bin/google-chrome -
MacOS:
/Applications/Google Chrome.app/Contents/MacOS/Google Chrome -
Windows:
C:\Program Files\Google\Chrome\Application\chrome.exeORC:\Program Files (x86)\Google\Chrome\Application\chrome.exe
Custom Chrome Executable
If you have a custom Chrome executable or a different path, you can set the CHROME_EXECUTABLE_PATH environment variable to the path of your Chrome executable:
export CHROME_EXECUTABLE_PATH=/path/to/your/chrome
npm run dev
For more details on where this is checked look at api/src/utils/browser.ts.
🏄🏽♂️ Usage
If you're looking for quick examples on how to use Steel, check out the Cookbook.
Alternatively you can play with the REPL package too
cd replandnpm run start
There are three main ways to interact with the Steel browser API:
In these examples, we assume your custom Steel API endpoint is http://localhost:3000.
The full REST OpenAPI documentation can be found on our site and on your local Steel instance at http://localhost:3000/documentation.
Using the SDKs
If you prefer to use the our Python and Node SDKs, you can install the steel-sdk package for Node or Python.
These SDKs are built on top of the REST API and provide a more convenient way to interact with the Steel browser API. They are fully typed, and are compatible with both Steel Cloud and self-hosted Steel instances (changeable using the baseURL option on Node and base_url on Python).
For more details on installing and using the SDKs, please see the Node SDK Reference and the Python SDK Reference.
Sessions
The /sessions endpoint lets you relaunch the browser with custom options or extensions (e.g. with a custom proxy) and also reset the browser state. Perfect for complex, stateful workflows that need fine-grained control.
Once you have a session, you can use the session ID or the root URL to interact with the browser. To do this, you will need to use Puppeteer or Playwright. You can find some examples of how to use Puppeteer and Playwright with Steel in the docs below:
import Steel from "steel-sdk";
const client = new Steel({
baseURL: "http://localhost:3000", // Custom API Base URL override
});
(async () => {
try {
// Create a new browser session with current API fields
const session = await client.sessions.create({
blockAds: true,
proxyUrl: "user:pass@host:port", // optional
dimensions: { width: 1280, height: 800 }, // optional
});
console.log("Created session with ID:", session.id);
} catch (error) {
console.error("Error creating session:", error);
}
})();
import os
from steel import Steel
client = Steel(
base_url="http://localhost:3000", # Custom API Base URL override
)
try:
# Create a new browser session with custom options
session = client.sessions.create(
block_ads=True,
proxy_url="user:pass@host:port", # optional
dimensions={"width": 1280, "height": 800}, # optional
)
print("Created session with ID:", session.id)
except Exception as e:
print("Error creating session:", e)
# Launch a new browser session
curl -X POST http://localhost:3000/v1/sessions \
-H "Content-Type: application/json" \
-d '{
"proxyUrl": "user:pass@host:port",
"blockAds": true,
"dimensions": { "width": 1280, "height": 800 }
}'
Selenium Sessions
Note: This integration does not support all the features of the CDP-based browser sessions API.
For teams with existing Selenium workflows, the Steel browser provides a drop-in replacement that adds enhanced features while maintaining compatibility. You can simply use the isSelenium option to create a Selenium session:
// Using the Node SDK
const session = await client.sessions.create({ isSelenium: true });
# Using the Python SDK
session = client.sessions.create(is_selenium=True)
# Launch a Selenium session
curl -X POST http://localhost:3000/v1/sessions \
-H "Content-Type: application/json" \
-d '{
"isSelenium": true
}'
The Selenium API is fully compatible with Selenium's WebDriver protocol, so you can use any existing Selenium clients to connect to the Steel browser. For more details on using Selenium with Steel, refer to the Selenium Docs.
Quick Actions API
The /scrape, /screenshot, and /pdf endpoints let you quickly extract clean, well-formatted data from any webpage using the running Steel server. Ideal for simple, read-only, on-demand jobs:
Extract the HTML content of a web page.
# Example using the Actions API
curl -X POST http://0.0.0.0:3000/v1/scrape \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"delay": 1000
}'
Take a screenshot of a web page.
# Example using the Actions API
curl -X POST http://0.0.0.0:3000/v1/screenshot \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"fullPage": true
}' --output screenshot.png
Download a PDF of a web page.
# Example using the Actions API
curl -X POST http://0.0.0.0:3000/v1/pdf \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com"
}' --output output.pdf
Commands API
The /sessions/{sessionId}/commands endpoint drives the session's browser with high-level commands. It is built for AI agents: take a snapshot of the page, then act on elements by the refs in the snapshot. One request can run several commands and return the new page state.
The commands API is experimental and off by default. Start the server with ENABLE_COMMANDS_API=true to turn it on.
curl -X POST http://localhost:3000/v1/sessions/$SESSION_ID/commands \
-H "Content-Type: application/json" \
-d '{
"commands": [
{ "command": "navigate", "url": "https://example.com" },
{ "command": "snapshot", "interactive": true }
]
}'
The response holds the snapshot, for example - link "Learn more" [ref=e1]. Send { "command": "click", "target": "e1" } to click the link. See the Commands API docs for every command, the response format, and error codes.
Get involved
Steel browser is an open-source project, and we welcome contributions!
License
Made with ❤️ by the Steel team.