# Browsing
**Rust-native browser automation β 20+ CDP managers, MCP server, zero AI deps**
| **Binary size** | ~2β5 MB release (LTO + strip + `opt-level = "z"`) |
| **Test coverage** | 360+ tests, all passing |
| **CDP domains covered** | Page, Network, Fetch, Emulation, Tracing, Profiler, CSS, DOM, Runtime, Target, ServiceWorker, Input, Browser, Console |
| **Zero** | LLM dependencies, `Box::leak`, recursive async retry |
## πΊοΈ Where Does Browsing Fit?
| Selenium | Java/Python | Legacy testing | Heavy WebDriver | Indirect |
| Puppeteer | JavaScript | Chrome scripts | ~50 MB Node | Thin wrapper |
| Playwright | JS/Python | Cross-browser tests | ~200 MB | Batteries-included, opinionated |
| browser-use | Python | LLM agents | Python + AI deps | Hidden behind agent loop |
| **Browsing** | **Rust** | **Fast, embeddable automation** | **~2β5 MB** | **Raw + 20 typed managers** |
Browsing gives you Playwright's feature coverage (dialogs, file choosers, device presets, permissions, HAR, tracing, touch, workers, service workers) in a Rust-native, zero-bloat package with an MCP server for LLM integration.
## π― Key Features
### ποΈ Architecture
- **Trait-based** β `BrowserClient`, `DOMProcessor`, `ActionHandler` for mocking and backends
- **20+ typed managers** β Each wraps a CDP domain: Dialog, FileChooser, Permissions, HAR, Interceptor, Performance, Coverage, Tracing, Touch, Worker, ServiceWorker, Viewport (with device presets, color scheme, vision deficiency, locale), Auth, Console, Cookies, PDF
- **Headless by default** β 17+ lightweight Chrome flags; `BrowserProfile::default()` runs `--headless=new`
- **Raw CDP access** β `Browser::raw_cdp_command()` for anything the managers don't cover
- **Zero AI dependencies** β Pure Rust, no LLM lock-in
## π¦ Installation
### As a Library
```toml
[dependencies]
browsing = "0.1"
tokio = { version = "1.40", features = ["full"] }
```
### As a CLI Tool
```bash
cargo install --path . --bin browsing
```
### As an MCP Server
```bash
cargo build --release --bin browsing-mcp
```
## π Quick Start
### 1οΈβ£ CLI Usage
```bash
# Run a browser automation task (headless by default)
browsing run "Navigate to example.com and extract content" --url https://news.ycombinator.com
# Run with visible browser
browsing run "Navigate to example.com and extract content" --url https://news.ycombinator.com --no-headless
# Launch a headless browser and get CDP URL (headless by default)
browsing launch
# Launch with visible browser
browsing launch --no-headless
# Connect to existing browser
browsing connect ws://localhost:9222/devtools/browser/abc123
```
**π [Full CLI Documentation](docs/CLI_USAGE.md)**
### 2οΈβ£ MCP Server Usage
Configure in Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"browsing": {
"command": "/path/to/browsing/target/release/browsing-mcp",
"env": {
"BROWSER_USE_HEADLESS": "true"
}
}
}
}
```
Then ask Claude:
```
"Navigate to rust-lang.org, get the links, follow the second link, and screenshot the main content area"
```
**π [Full MCP Documentation](docs/MCP_USAGE.md)**
### 3οΈβ£ Library Usage
```rust
use anyhow::Result;
use browsing::Browser;
use browsing::browser::BrowserProfile;
#[tokio::main]
async fn main() -> Result<()> {
browsing::init();
let mut browser = Browser::new(BrowserProfile::default());
browser.start().await?;
browser.navigate("https://example.com").await?;
let title = browser.get_current_page_title().await?;
println!("Title: {}", title);
let _ = browser.stop().await;
Ok(())
}
```
**π [Full Library Documentation](docs/LIBRARY_USAGE.md)**
### Browser Launch Options
```rust
use browsing::{Browser, BrowserProfile};
// Option 1: Auto-launch headless browser (default)
let profile = BrowserProfile::default(); // headless = true by default
let browser = Browser::new(profile);
// Option 2: Launch with visible browser
let profile = BrowserProfile::default().with_headless(false);
let browser = Browser::new(profile);
// Option 3: Connect to existing browser
let browser = Browser::new(BrowserProfile::default())
.with_cdp_url("http://localhost:9222".to_string());
// Option 4: Custom browser executable
use browsing::browser::launcher::BrowserLauncher;
let launcher = BrowserLauncher::new(profile)
.with_executable_path(std::path::PathBuf::from("/path/to/chrome"));
```
## π Quick Example
```rust
use browsing::browser::{Browser, BrowserProfile};
#[tokio::main]
async fn main() -> browsing::Result<()> {
let mut browser = Browser::new(BrowserProfile::default());
browser.start().await?;
browser.navigate("https://example.com").await?;
// Use any manager
let viewport = browser.viewport_manager()?;
viewport.preset_device(&browsing::DevicePreset::iphone_15()).await?;
// Or send raw CDP
let result = browser
.raw_cdp_command("Runtime.evaluate", json!({"expression": "1+1"}))
.await?;
Ok(())
}
```
**More examples:** See [`examples/`](examples/) β device emulation, dialog handling, HAR capture, permissions, touch gestures, raw CDP access.
## ποΈ Architecture
```
ββββββββββββ¬βββββββββββββββ¬βββββββββββββββββββββββββ
β Browser β DOMProcessor β Tools β
β (trait) β (trait) β β
ββββββ¬ββββββ΄βββββββ¬ββββββββ΄ββββββββββββββββ¬βββββββββ
β β β
ββββββΌβββββ βββββΌβββββ βββββββββββΌβββββββ
β Browser β β DomSvc β β Handlers β
β Session β β β β (nav, click, β
β + 20+ β β CDP β β tabs, content)β
β managersβ β HTML β β β
βββββββββββ ββββββββββ ββββββββββββββββββ
```
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for full design.
## π Project Structure
```
browsing/
βββ src/
β βββ agent/ # Agent view types (used by tools layer)
β β βββ views.rs # Data types
β β βββ memory.rs # Session memory types
β βββ browser/ # Browser management
β β βββ session.rs # Browser session (BrowserClient impl)
β β βββ tab_manager.rs # Tab operations
β β βββ navigation.rs # Navigation operations
β β βββ screenshot.rs # Screenshot operations
β β βββ cdp.rs # CDP WebSocket client
β β βββ launcher.rs # Browser launcher
β β βββ profile.rs # Browser configuration
β β βββ auth.rs # HTTP auth / proxy / extra headers
β β βββ console.rs # Console log capture
β β βββ cookies.rs # Cookie management
β β βββ coverage.rs # JS/CSS coverage tracking
β β βββ dialog.rs # Dialog handling (alert/confirm/prompt)
β β βββ download.rs # Download monitoring
β β βββ filechooser.rs # File chooser interception
β β βββ har.rs # Network traffic HAR capture
β β βββ interceptor.rs # Network request interception
β β βββ pdf.rs # PDF export
β β βββ performance.rs # Performance metrics
β β βββ permissions.rs # Browser permissions API
β β βββ serviceworker.rs # Service worker management
β β βββ touch.rs # Touch gesture emulation
β β βββ tracing.rs # Chrome tracing / CPU profiling
β β βββ viewport.rs # Viewport / device emulation
β β βββ worker.rs # Web worker management
β β βββ views.rs # Data types
β βββ dom/ # DOM processing
β β βββ processor.rs # DOMProcessor trait impl
β β βββ serializer.rs # Text serialization
β β βββ tree_builder.rs # DOM tree construction
β β βββ cdp_client.rs # CDP wrapper for DOM
β β βββ html_converter.rs # HTML to markdown
β βββ tools/ # Action system
β β βββ service.rs # Tools registry
β β βββ handlers/ # Action handlers
β β β βββ navigation.rs
β β β βββ interaction.rs
β β β βββ tabs.rs
β β β βββ content.rs
β β β βββ advanced.rs
β β βββ params.rs # Parameter extraction
β βββ traits/ # Core trait abstractions
β β βββ browser_client.rs # BrowserClient trait
β β βββ dom_processor.rs # DOMProcessor trait
β βββ actor/ # Low-level interactions
β β βββ page.rs # Page operations
β β βββ element.rs # Element operations
β β βββ mouse.rs # Mouse interactions
β β βββ keyboard.rs # Keyboard input
β βββ config.rs # Configuration
β βββ error.rs # Error types
β βββ logging.rs # Logging setup
β βββ metrics.rs # Metrics collection
β βββ utils.rs # Utilities
β βββ views.rs # Shared data types
βββ Cargo.toml
```
## π§ͺ Testing
```bash
# Run all tests
cargo test
# Run with output
cargo test -- --nocapture
# Run specific test
cargo test test_browser_navigation
# Run integration tests only
cargo test --test integration
```
### Test Coverage
**360+ tests**, all passing, 0 ignored. Every manager has unit tests. Mock implementations for deterministic testing without real browsers.
| Actor | 29 | Page, Element, Mouse, Keyboard |
| Browser | 154 | All 20+ managers + lifecycle |
| Tools | 67 | Action handlers + registry |
| Traits | 27 | BrowserClient, DOMProcessor mocks |
| Utils | 52 | URL extraction, signals |
| Integration | 115+ | End-to-end workflows |
## β οΈ Data Retention
Browser data is **never deleted** to prevent accidental loss of real profiles. Temp directories in `/tmp/browser-use-*` are left for inspection; clean them manually.
```bash
rm -rf /tmp/browser-use-*
```
## π§ Configuration
```rust
use browsing::BrowserProfile;
let profile = BrowserProfile::default(); // headless, lightweight flags
let profile = BrowserProfile::default().with_headless(false); // visible
let profile = BrowserProfile {
user_data_dir: Some("/path/to/profile".into()),
..Default::default()
};
```
## π API Documentation
Generate and view API docs:
```bash
cargo doc --open
```