π 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 β Native
OXICDP domain withgetMarkdown(),getPageInfo(), and text-first rendering - β‘ 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 β 21 MB binary, ~8 MB base memory. Run 100 instances without breaking a sweat
π Quick Start
Install
Cargo (all platforms)
Build from source
# Binary at ./target/release/oxibrowser
Use as a library
# Cargo.toml
[]
= "0.7"
Fetch a page
Start CDP server
Then connect with Puppeteer:
import puppeteer from 'puppeteer-core';
const browser = await puppeteer.;
const page = await browser.;
await page.;
// Get markdown β OxiBrowser's AI-native feature
const md = await page.;
console.log;
await browser.;
Rust API
use Browser;
use BrowserConfig;
async
π 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 |
1,233 | Binary + CLI (fetch, serve, version) |
oxibrowser-core |
12,953 | Browser engine: Session, Page, Frame, JS Runtime |
oxibrowser-cdp |
4,392 | CDP WebSocket server with 10 domain handlers |
oxibrowser-webapi |
1,549 | DOM tree, CSS selectors, Markdown conversion |
| Total | 20,127 |
π Features
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
The OXI CDP domain provides AI-optimized APIs that no other browser offers:
= await
# Navigate
await
await
# Get clean markdown β perfect for LLM ingestion
await
=
# Clean markdown output
# Get structured page info
await
=
# title, url, status, content-type, etc.
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 279 tests
# E2E CDP tests (23 tests with real WebSocket)
# Integration tests (real websites, --ignored)
# Puppeteer smoke tests
π CLI Reference
oxibrowser 0.7.0
Headless browser with CDP support
USAGE:
oxibrowser <COMMAND>
COMMANDS:
fetch Fetch and render a URL
serve Start CDP WebSocket server
version Print version information
FETCH OPTIONS:
<URL> URL to fetch
--dump <FORMAT> Output format: text, html, markdown [default: text]
SERVE OPTIONS:
--host <HOST> Bind address [default: 127.0.0.1]
--port <PORT> Bind port [default: 9222]
--obey-robots Respect robots.txt
--log-level <LEVEL> Log level: trace, debug, info, warn, error [default: info]
π§ Advanced Usage
Custom Browser Configuration
use ;
use Duration;
let config = BrowserConfig ;
let browser = new.await?;
Request Interception
// With Puppeteer
const client = await page..;
await client.;
client.;
Screenshot Capture
// PNG screenshot via CDP
const = await client.;
// data is base64-encoded PNG
π€ Contributing
Contributions are welcome! Whether it's:
- π Bug reports β Open an issue
- π‘ Feature requests β Start a discussion
- π§ Pull requests β Fork, branch, PR. All PRs need passing tests.
- π Documentation β Fix typos, add examples, improve guides
Development Setup
π License
OxiBrowser is licensed under the MIT License.
π Acknowledgments
- Lightpanda β Architecture inspiration (Browser β Session β Page β Frame hierarchy)
- 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