Web Storage was a plain object inside the V8 realm, and `Page::init_js` builds a new realm on every navigation, so every entry was dropped by the next document. localStorage now lives on the BrowserContext and sessionStorage on the Page, both in Rust keyed by origin, with per-origin and total quotas. Under `--storage-dir`, localStorage is written per origin after a document's scripts run and on shutdown, and read back when a context is created. Only origins that changed since the last successful write are touched, a clear or a last-key removal unlinks the file instead of letting the next load resurrect it, and a failed write leaves the store dirty so it is retried. sessionStorage stays in memory: it is per tab, like a real browser, but it now survives navigation and CDP target switching within the process. `obscura mcp` never passed `--storage-dir` to its BrowserContext, so that path persisted nothing, cookies included. It reads the profile from OBSCURA_STORAGE_DIR, set by the CLI from the global flag, and flushes on exit. IndexedDB was a shim that handed every object store its own Map and never fired onupgradeneeded, so a schema-created database was unreachable and the first read threw. Records and the schema live in an origin-keyed store on the context, and the shim implements the spec shape: versionchange transactions, real objectStoreNames, NotFoundError, asynchronous request settlement, transactions that complete on a macrotask so chained requests work, key paths, generators, indexes and cursors. Values round-trip through JSON. Fixes #678.
Obscura is an open-source headless browser engine written in Rust. It runs JavaScript via V8, speaks the Chrome DevTools Protocol, and works as a drop-in replacement for headless Chrome with Puppeteer and Playwright.
Versus headless Chrome
| Metric | Obscura | Headless Chrome |
|---|---|---|
| Memory | 30 MB | 200+ MB |
| Binary size | ~70 MiB | 300+ MB |
| Startup | Instant | ~2s |
| Page load | 85 ms | ~500 ms |
| Anti-detect | Built-in | None |
| Puppeteer | Yes | Yes |
| Playwright | Yes | Yes |
Rendering and stealth are both first-class capabilities. Release builds support screenshots, scroll-aware layout, activity-driven CDP screencasting, and raster PDF export; stealth builds retain all of those surfaces while adding the wreq/BoringSSL transport and browser-identity protections.
Quickstart
Guides
- Build from source
- Configure stealth and proxies
- Markdown extraction
- Use with Puppeteer
- Use with Playwright
- Use the MCP server
- Use as a Rust library
- Persist cookies and storage
- Intercept and modify requests
- Run in production at scale
Reference
Contributing
Links
- Source: https://github.com/h4ckf0r0day/obscura
- Releases: https://github.com/h4ckf0r0day/obscura/releases
- Issues: https://github.com/h4ckf0r0day/obscura/issues
License: Apache-2.0.