Web Scraping APIs

What Is Obscura?

What Is Obscura? — conceptual illustration
On this page

Obscura is an open-source headless browser engine written from scratch in Rust — not a fork or patch of Chrome or Firefox. A headless browser is one with no visible window, driven by code. Obscura runs a page's JavaScript using V8 (Google's JS engine, embedded here via the deno_core crate) against a page structure built by html5ever, and it speaks the Chrome DevTools Protocol — the same control channel real Chrome exposes — so Puppeteer/Playwright can drive it. At ~30MB and ~85ms per page it is by far the lightest tool here. But it has no layout engine, no CSS cascade, and no real canvas/WebGL — it never actually draws the page — and that is exactly what limits it against fingerprint-aware anti-bots.

Quick facts

TypeFrom-scratch headless engine (V8 + html5ever)
LanguageRust (CLI/engine); any language via CDP clients
Footprint~30MB binary, ~85ms page load — high concurrency
StealthJavaScript shim (navigator overrides) + optional TLS via --features stealth
Hard limitNo layout/rendering — getBoundingClientRect returns all zeros

How Obscura works

Obscura is a Cargo workspace (a multi-part Rust project) of six crates: a CLI (fetch/scrape/serve + load balancer), a CDP WebSocket server that automation tools connect to, a Page abstraction, an HTTP client (reqwest by default, or wreq for TLS impersonation — copying a real browser's encryption handshake — under --features stealth), the V8 JavaScript runtime, and an html5ever DOM with the selectors crate for CSS queries. When you navigate to a page, it fetches the HTML, parses it, fetches the CSS in parallel (but only keeps it as a string — it never applies it), starts V8 from a precompiled snapshot for fast boot, and runs the page's scripts.

All anti-detection lives in a single 3,035-line bootstrap.js shim that runs before the page's own scripts. It fakes a browser environment in JavaScript: it defines navigator with webdriver=undefined (the flag that gives automation away), a Chrome 145 user-agent, userAgentData/UA-CH payloads (the structured browser-identity hints sites read), a 5-plugin list, and stubs for mediaDevices/battery/permissions. There are no C++ or binary patches — every override is plain JavaScript.

Why it is weak against real anti-bots

Obscura is not a full browser, and detectors notice. Because it has no layout engine — nothing that computes where elements sit on screen — getBoundingClientRect() returns {0,0,0,0} for every element and getComputedStyle returns placeholder values. Real browsers never do that, so Layer-5 (rendering/layout) probes catch it at once. Its canvas, WebGL, and audio are not real implementations either, so any fingerprinting service that hashes the actual pixels a browser draws will flag it instantly. The user-agent is hardcoded Linux. In practice it satisfies only basic navigator.webdriver-style checks; against DataDome, Kasada, Akamai, PerimeterX, or even Cloudflare beyond the free tier, it fails.

When to use Obscura

Use it when: you need to run JavaScript on unprotected pages at high volume and a real Chrome instance (~200MB each) is too heavy — Obscura's ~30MB workers let you run many at once on the same machine. The repo suggests a hybrid setup: Obscura handles the easy bulk, while Patchright/Camoufox handle the few protected targets. Avoid it when: the target uses any fingerprint-aware or layout-probing detection — Obscura has no answer to those. Think of it as a lightweight JS-rendering engine, not an anti-detect browser.

Code example

bash
# Lightweight JS rendering for unprotected pages, optional TLS stealth
obscura fetch https://example.com --dump-text

# Or run as a CDP server and drive it from Puppeteer/Playwright clients
obscura serve --port 9222
# Build with TLS impersonation: cargo build --release --features stealth

Related terms

Concept map

How Obscura connects

The terms most directly tied to this one. Hover a node to see its neighbours, click to preview, drag to rearrange.

0 terms · 0 connections
You are here · Web Scraping APIs
Building map…

Frequently asked questions

Is Obscura a real browser?

No. It is a from-scratch engine that runs JavaScript (V8) against an html5ever DOM, but it has no layout engine, no CSS cascade, no compositor, and no real canvas/WebGL/audio — so it never actually renders the page. It reimplements just enough of the browser surface to execute page scripts, which is why it is so lightweight.

Why does Obscura fail against anti-bot systems?

Its missing layout engine is a dead giveaway: getBoundingClientRect returns all zeros and getComputedStyle returns stub values, which Layer-5 rendering probes catch immediately because a real browser never does that. Its canvas/WebGL are not real, so fingerprinting services that hash the actual drawn output flag it. It only satisfies basic navigator.webdriver checks.

When would I choose Obscura over Chrome?

When you need to render JavaScript on unprotected pages at high concurrency. At ~30MB and ~85ms per load you can run far more workers in parallel than with ~200MB Chrome instances. The recommended pattern is hybrid — Obscura for the easy bulk, Patchright/Camoufox for the protected pages.

Does Obscura impersonate TLS?

Optionally. TLS is the encryption layer behind https, and its handshake leaves a recognizable fingerprint. Built with --features stealth, Obscura swaps reqwest for the wreq client to present a Chrome 145 TLS fingerprint. That is a single profile, not the broad impersonation library that Scrapling's curl_cffi tier offers.

Last updated: 2026-05-31