What is Obscura — An Open-Source Headless Browser Engine

Obscura is a Rust-powered headless browser engine purpose-built for AI agent automation and web scraping. 30 MB memory, 85 ms page load, built-in stealth, CDP-compatible.

16Yun Engineering TeamJun 30, 20265 min read

A New Choice for Headless Browsing

Developers doing web scraping and AI agent automation almost always end up using Headless Chrome. It is feature-complete, but it comes with persistent pain points:

  • Memory bloat: A single instance easily consumes 200+ MB
  • Slow startup: Cold start takes ~2 seconds, costs add up in batch rotation
  • No anti-detection: Exposes navigator.webdriver by default, TLS fingerprint differs from real Chrome
  • Large binary: 300+ MB makes container images bulky

Obscura was built from the ground up to solve these problems.

What is Obscura

Obscura is an open-source headless browser engine written in Rust. It embeds the V8 JavaScript engine (via deno_core), maintains a real DOM tree, and exposes the Chrome DevTools Protocol (CDP) so it can replace Headless Chrome for Puppeteer and Playwright.

The project is open-sourced on GitHub under the Apache 2.0 license.

Key Metrics

MetricObscuraHeadless Chrome
Runtime memory~30 MB200+ MB
Binary size~70 MB300+ MB
Page load (static)~51 ms~500 ms
Page load (JS+XHR)~84 ms~800 ms
Cold startInstant~2 s
Anti-detectionBuilt-in StealthNone
PuppeteerYes (CDP)Yes
PlaywrightYes (CDP)Yes
LicenseApache 2.0BSD

Benchmark data and source code are publicly available on GitHub.

Three Ways to Use It

Obscura provides three integration levels for different scenarios. Understanding the difference is the first step in choosing between them: the CLI is for one-off fetches and shell orchestration, the CDP server is for migrating existing Puppeteer/Playwright code, and MCP is for letting a large language model drive the browser directly.

1. CLI

Download a single binary. No Chrome, Node.js, or dependencies. Fetch pages directly:

obscura fetch https://example.com --dump text
obscura fetch https://httpbin.org/anything --eval "document.title"
obscura scrape url1 url2 url3 --concurrency 25 --format json

This is the lightest approach. One command equals one full headless browser.

2. CDP Protocol Server

Start a WebSocket server and connect with Puppeteer or Playwright:

obscura serve --port 9222

Puppeteer:

import puppeteer from 'puppeteer-core';
 
const browser = await puppeteer.connect({
  browserWSEndpoint: 'ws://127.0.0.1:9222/devtools/browser',
});
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.title());
await browser.disconnect();

Playwright:

import { chromium } from 'playwright-core';
 
const browser = await chromium.connectOverCDP('ws://127.0.0.1:9222');
const page = await browser.newContext().then(ctx => ctx.newPage());
await page.goto('https://example.com');
console.log(await page.title());
await browser.close();

Note that Playwright uses connectOverCDP (pass the WebSocket endpoint as a string). Do not use connect, which speaks Playwright's private protocol that Obscura does not implement.

3. MCP Server

Expose browser tools to AI agents:

obscura mcp

Claude Desktop, Claude Code, and Cursor can call browser tools like browser_navigate, browser_click, browser_fill, and browser_snapshot. The tools cover navigation, reading, interaction, waiting, cookies, and tab management, letting a large language model drive a browser the way it calls a function.

Stealth Anti-Detection

Obscura ships with built-in Stealth mode, enabled with --stealth:

obscura fetch https://example.16yun.cn --stealth
obscura serve --stealth
obscura scrape url1 url2 --stealth
obscura mcp --stealth

Stealth mode does the following:

  • TLS fingerprint spoofing: Uses wreq (BoringSSL) to present a real Chrome ClientHello
  • Browser profiles: A built-in pool of realistic profiles (Windows and macOS, recent Chrome versions) with internally consistent navigator.platform, userAgentData, UA, and GPU renderer
  • API masking: navigator.webdriver = undefined, Function.prototype.toString returns [native code]
  • Tracker blocking: Bundled Peter Lowe blocklist, 3500+ domains, blocks analytics and ads automatically

One caveat worth stating plainly: Stealth is not a silver bullet. It defeats passive detection based on TLS fingerprint and JS surface, but Cloudflare interactive challenges, CAPTCHAs, and active bot managers like Datadome still require pairing with residential proxies.

Request Interception

Obscura provides full control over network requests. Intercept from Puppeteer via CDP Fetch.enable, or from the Rust library via enable_interception:

// Puppeteer interception
page.on('request', req => {
  if (req.resourceType() === 'image') req.abort();
  else req.continue();
});
// Rust library interception
let mut rx = page.enable_interception();
while let Some(req) = rx.recv().await {
    if req.url.contains("/ads") {
        req.resolver.send(InterceptResolution::Fail { reason: "blocked".into() });
    } else {
        req.resolver.send(InterceptResolution::Continue { url: None, method: None, headers: None, body: None });
    }
}

Interception pays off far beyond ad blocking in real projects: dropping images and fonts during bulk collection can cut bandwidth and load time by multiples; replacing a feature-flag endpoint with a mock response bypasses front-end gating; and listening on on_response is the main way to capture the JSON an SPA loads asynchronously.

Why Rust

Obscura chose Rust for clear design reasons:

  • Memory safety: No GC, no runtime overhead, ensures long-running browser processes do not leak
  • Performance: Direct V8 C API calls without an extra language bridge layer
  • Single binary: Static compilation, no runtime dependencies
  • Concurrency model: tokio async runtime, suitable for high-concurrency scraping

When to Choose Obscura

Use Obscura for:

  • High-density scraping requiring many parallel instances
  • AI agent browser automation needing fast startup and teardown
  • Constrained environments (Docker, CI/CD, edge nodes) where binary size matters
  • Tasks requiring anti-detection capabilities

Stick with Headless Chrome for:

  • Full Chrome DevTools panels (Performance, Memory analysis)
  • Chrome-only features (Extension testing)
  • Maximum rendering fidelity when resources are not a concern

The rule of thumb is simple: if your work is mostly "read the page, run JS, extract data", Obscura's light footprint and stealth are clear wins; if you need pixel-level rendering, DevTools performance profiling, or the Chrome extension ecosystem, Chrome remains the safer bet.

Quick Start

Download and run in three steps:

# 1. Download (replace example.16yun.cn with the actual release page)
curl -LO https://example.16yun.cn/obscura/releases/latest/download/obscura-x86_64-linux.tar.gz
tar xzf obscura-x86_64-linux.tar.gz
 
# 2. Fetch
./obscura fetch https://example.com --dump markdown
 
# 3. Serve
./obscura serve --port 9222

Or use Docker:

docker run -d --name obscura -p 127.0.0.1:9222:9222 h4ckf0r0day/obscura

Summary

Obscura is not a full-featured browser. It is a headless browser engine optimized specifically for automation scenarios. Its value proposition is clear: smaller, faster, stealthier, and easier to deploy at scale.

The following articles in this series will dive into each core capability: CLI commands, CDP compatibility, Stealth mechanics, MCP AI integration, architecture, production deployment, request interception, Rust library integration, and reliability design.

Need an enterprise proxy plan?

We can tailor architecture to your target domains, concurrency, and reliability goals.