π OxiBrowser
The headless browser built in pure Rust for AI agents.
Not a Chromium fork. Not a C++ wrapper. A browser engine written from scratch in Rust, designed from day one for automation, web scraping, and AI-driven workflows.
Report Bug Β· Request Feature Β· Read the Docs Β· Discord
β¨ Why OxiBrowser?
You're building AI agents that need to browse the web. You don't need a full browser with GPU rendering, audio output, and extension support. You need something fast, small, and programmable.
OxiBrowser is built for exactly that use case:
- π€ AI-Agent First β CLI designed for agents:
--jsonoutput,describefor schema,skillfor prompts,sessionfor multi-step - β‘ Blazing Fast β Cold starts in ~50ms, no Chromium overhead, no Node.js required
- π¦ Pure Rust β Zero C dependencies.
boa_enginefor JS (no V8). Single static binary. Memory-safe. - π CDP Compatible β Puppeteer, Playwright, and any Chrome DevTools Protocol client works out of the box
- π‘οΈ Secure by Default β SSRF protection with CIDR blocking,
robots.txtrespect, no sandbox escape surface - π¦ Tiny Footprint β 24 MB binary, ~8 MB base memory. Run 100 instances without breaking a sweat
π Quick Start
Install
Fetch a page (human-readable)
# Example Domain
)
Fetch a page (agent mode)
}}}
Extract structured data
}}
Multi-step session (stdin/stdout JSON REPL)
}}
}}
}}
}}
}}
Start CDP server (Puppeteer/Playwright)
import puppeteer from 'puppeteer-core';
const browser = await puppeteer.;
const page = await browser.;
await page.;
console.log;
await browser.;
π CLI Reference
oxibrowser <COMMAND>
COMMANDS:
fetch Fetch a URL and return content (markdown default)
extract Extract structured data (links, text, elements)
run Run a YAML automation script
session Interactive stdin/stdout JSON REPL (22 commands)
serve Start CDP WebSocket server
describe Print CLI schema as JSON (for agents)
skill Print agent skill guide
version Print version information
fetch β One-shot page fetch
# Human-readable (markdown, default)
# Agent mode
# Click then read
# Quick page summary
# Run JS
# Limit response size
# Select specific fields
extract β Structured data extraction
# Get all links
# Extract elements by CSS selector
# Title + full text
session β Multi-step automation
# 22 commands:
describe β Agent introspection
# Compact (~200 tokens)
# Full command details
run β YAML automation
name: example
steps:
- step_type: goto
data:
goto: https://example.com
- step_type: content
data:
format: markdown
JSON Output Format
All --json responses follow the same schema:
On error:
Exit codes: 0=success, 1=runtime, 2=input validation, 3=timeout, 4=network
π Architecture
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Puppeteer / Playwright / Rust CDP β
ββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββ
β CDP WebSocket
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CDP Server (10 domains) β
β Browser Β· DOM Β· Fetch Β· Input Β· Network β
β OXI Β· Page Β· Runtime Β· Target β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Browser β Session β Page β Frame β
ββββββββββββ¬βββββββββββ¬βββββββββββββββ¬ββββββββββββββββββ€
β WebAPI β Network β JS Runtime β CSS Rendering β
β DOM β HTTP β boa_engine β PNG screenshot β
β Tree β Cookies β ES2024+ β ASCII/Unicode β
β Storage β SSRF β persistent β textβimage β
ββββββββββββ΄βββββββββββ΄βββββββββββββββ΄ββββββββββββββββββ€
β html5ever Β· encoding_rs Β· reqwest Β· image Β· boa β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Crate Structure
| Crate | Lines | Purpose |
|---|---|---|
oxibrowser |
4,242 | Binary + CLI (8 subcommands, session REPL, agent features) |
oxibrowser-core |
19,794 | Browser engine: Session, Page, Frame, JS Runtime |
oxibrowser-cdp |
4,583 | CDP WebSocket server with 10 domain handlers |
oxibrowser-webapi |
1,587 | DOM tree, CSS selectors, Markdown conversion |
| Total | 30,206 |
π Features
Agent-First CLI
Designed for AI agent workflows β no daemon, no socket, single binary:
| Feature | Description |
|---|---|
--json |
Machine-readable output (opt-in, human by default) |
--max-bytes N |
Truncate response to N bytes |
--fields a,b,c |
Select specific output fields |
--summary |
Quick page metadata (title, links, headings) |
describe |
CLI schema as JSON for agent introspection |
skill |
Agent skill guide for prompt injection |
session |
Stdin/stdout JSON REPL with 22 commands |
| Exit codes | 0=success, 1=runtime, 2=input, 3=timeout, 4=network |
JavaScript Runtime (ES2024+)
Powered by boa_engine β pure Rust, no V8 dependency:
| Web API | Status |
|---|---|
document.querySelector / querySelectorAll |
β Full |
document.createElement / createTextNode |
β Full |
element.appendChild / removeChild / insertBefore |
β Full |
element.getAttribute / setAttribute / removeAttribute |
β Full |
element.cloneNode / remove() |
β Full |
element.style (CSSStyleDeclaration) |
β Property accessor |
element.classList (DOMTokenList) |
β Property accessor |
element.textContent / innerHTML |
β Read/Write |
element.addEventListener / dispatchEvent |
β Full |
element.click() |
β With event handlers |
fetch() |
β Full (channel bridge) |
XMLHttpRequest |
β Full with callbacks |
localStorage |
β Persistent |
MutationObserver |
β observe/disconnect/takeRecords |
setTimeout / setInterval |
β TokioJobQueue |
console.log/warn/error |
β With formatting |
URL / URLSearchParams |
β Full |
crypto.getRandomValues |
β Pseudo-random |
TextEncoder / TextDecoder |
β UTF-8 |
atob / btoa |
β Base64 |
requestAnimationFrame |
β Polyfill |
CDP Protocol (Chrome DevTools Protocol)
10 domain handlers β Puppeteer and Playwright compatible:
| Domain | Key Methods |
|---|---|
| Browser | getVersion, close |
| DOM | getDocument, describeNode, querySelector, querySelectorAll |
| Fetch | enable/disable, continueRequest, failRequest, fulfillRequest, getResponseBody |
| Input | dispatchKeyEvent, dispatchMouseEvent, insertText |
| Network | enable/disable, setExtraHTTPHeaders, getResponseBody |
| OXI π€ | getMarkdown, getPageInfo β AI-native extensions |
| Page | navigate, captureScreenshot, getFrameTree, getTitle |
| Runtime | evaluate, callFunctionOn, enable, consoleAPICalled |
| Target | getTargets, attachToTarget, detachFromTarget |
OXI Domain β Built for AI Agents
= await
await
await
# Clean markdown β perfect for LLM ingestion
await
=
Network Layer
| Feature | Description |
|---|---|
| HTTP Client | reqwest with cookie persistence, redirect following |
| Cookie Jar | Domain-scoped cookie storage with Set-Cookie parsing |
| SSRF Protection | CIDR blocking for private network ranges |
| robots.txt | RFC 9309 compliant parser, --obey-robots flag |
| Network Interception | Pause, modify, or block any request via Fetch domain |
| Custom Headers | Per-session and per-request header injection |
| Charset Detection | encoding_rs for automatic charset detection and conversion |
CSS Text Rendering
- ASCII/Unicode text output β Render DOM to readable text with proper indentation
- Markdown conversion β Full HTMLβMarkdown with heading, link, and list support
- PNG screenshots β Built-in 8Γ16 bitmap font, renders text content as images
- No external dependencies β Font data embedded in binary
π§ͺ Testing
# Run all tests
# CLI integration tests (fast, no network)
# E2E CDP tests
# Integration tests (real websites, requires internet)
π§ Advanced Usage
Rust API
use Browser;
use BrowserConfig;
async
Use as a library
[]
= "0.11"
# Or the CDP server:
= "0.11"
Request Interception
const client = await page..;
await client.;
client.;
π€ Contributing
See CONTRIBUTING.md for full guidelines.
π License
OxiBrowser is licensed under the MIT License.
π Acknowledgments
- boa_engine β Pure Rust JavaScript engine (ES2024+)
- html5ever β HTML parser from the Servo project
- reqwest β Ergonomic HTTP client for Rust
- tokio β Async runtime powering the entire networking stack
Made with π¦ in Rust