Agentic browser automation framework built in Rust. Anti-detection, accessibility tree extraction, and human-like interaction — designed for LLM-controlled browsing.
- Anti-Detection (Stealth) — WebDriver flag suppression, navigator spoofing, Chrome runtime stubs, canvas/WebGL fingerprint randomization, human-like timing delays
- Accessibility Tree Extraction — Compact text format optimized for LLM token efficiency
- Structured DOM Extraction — Forms, links, tables as JSON
- Human-Like Interaction — Gaussian-distributed delays, realistic keystroke timing
- Session Isolation — Separate cookies/storage per session via Chrome browser contexts
- Session Persistence — Save/restore cookies and state as JSON
use ironbrowser::{Browser, BrowserConfig};
#[tokio::main]
async fn main() -> Result<(), ironbrowser::BrowserError> {
let browser = Browser::launch(BrowserConfig::default()).await?;
let session = browser.new_session().await?;
let page = session.new_page().await?;
// Navigate
page.navigate("https://example.com").await?;
// Extract accessibility tree (most token-efficient for LLMs)
let tree = page.accessibility_tree().await?;
println!("{}", tree.to_compact_text(0));
// Extract structured data
let structure = page.extract_structured().await?;
println!("Forms: {}", structure.forms.len());
println!("Links: {}", structure.links.len());
// Interact
page.click("#some-button").await?;
page.type_text("#email", "user@example.com").await?;
page.select_option("#country", "AU").await?;
// Screenshot
let base64_png = page.screenshot_base64().await?;
page.close().await?;
session.close().await?;
browser.close().await?;
Ok(())
}The accessibility tree provides a compact, LLM-friendly view of the page:
[page] AusTender - Login
[heading] "Sign in to AusTender"
[textbox] "Email address" id=#email
[textbox] "Password" id=#password type=password
[button] "Sign in" id=#submit-btn
[link] "Forgot password?"
All evasion scripts are injected before any page JavaScript runs:
| Module | What it does |
|---|---|
webdriver |
Suppresses navigator.webdriver, removes cdc_* markers |
navigator |
Spoofs platform, vendor, languages, plugins to match UA |
chrome_runtime |
Injects window.chrome with runtime stubs |
fingerprint |
Adds noise to Canvas toDataURL(), WebGL vendor strings |
timing |
Gaussian-distributed delays for click/type/scroll |
user_agent |
UA rotation pool with consistent fingerprint profiles |
use ironbrowser::{BrowserConfig, StealthConfig, ResourceLimits};
use std::time::Duration;
let config = BrowserConfig {
headless: true,
stealth: StealthConfig {
enabled: true,
suppress_webdriver: true,
spoof_navigator: true,
randomize_fingerprint: true,
human_timing: true,
timing_variance_ms: (50, 200),
},
limits: ResourceLimits {
max_pages: 10,
navigation_timeout: Duration::from_secs(30),
..Default::default()
},
..Default::default()
};- Rust 1.85+
- Chrome or Chromium installed on the system
MIT