Rust-headless Browser Engine — Rust Core + Bun/JSC JS Runtime
  • TypeScript 45.1%
  • Rust 36.4%
  • HTML 18.5%
Find a file
None Of 0166ccdced fix: scrollIntoView uses Object.defineProperty to bypass linkedom readonly
- scrollIntoView(options) now uses Object.defineProperty with explicit
  writable/configurable/enumerable to avoid linkedom readonly property issue
- textarea.rows defaults to 2, cols to 20, wrap to 'soft' per HTML §4.10.8
- spec-coverage: 1156→1159 pass (all textarea defaults fixed)
2026-07-01 15:52:59 +00:00
.cargo chore: commit .cargo/mutants-direct.toml for reproducible cargo mutants runs 2026-06-26 11:20:33 +00:00
bench-results Sprint 29.0 Phase A+B+C+patch: SetDomArena robust + honest baseline 2026-06-25 05:45:56 +00:00
crates sprint 35: Stale-While-Revalidate + stale_resp routing 2026-07-01 13:12:00 +00:00
docs sprint 29.60: memory optimization — WindowProto sharing + lazy dom + JSON cleanup 2026-07-01 02:54:57 +00:00
fuzz sprint 29.7: extreme test coverage — fuzz infra + 12 proptest for DOM 2026-06-25 10:59:06 +00:00
js-runtime fix: scrollIntoView uses Object.defineProperty to bypass linkedom readonly 2026-07-01 15:52:59 +00:00
scripts chore: re-enable CI runner, update test baseline 2026-06-29 19:34:25 +00:00
sdks Sprint 18i: add sdks/.gitignore, remove pycache from tracking 2026-06-23 06:41:44 +00:00
test-data perf(css-selectors): ElementIndex — ID/Tag/Class HashMaps, Chrome-Level Performance 2026-06-20 20:11:53 +00:00
tests WAF: systematic identity-aware fetch + retry fix + inline-script execution 2026-06-30 17:05:19 +00:00
tools Sprint 29.0+: set_fetch_handler FFI + wiki_throughput bench + mirror_wiki tool 2026-06-25 09:58:05 +00:00
.gitignore fix: remove bun-vendor from index, add to gitignore 2026-06-30 13:31:45 +00:00
AGENDA.md verify: P4 done — BoringSSL Chrome 134 JA3 = Chrome 134 expected 2026-06-26 11:27:59 +00:00
bench-all.sh sprint 29.60: memory optimization — WindowProto sharing + lazy dom + JSON cleanup 2026-07-01 02:54:57 +00:00
bun.lock Canvas recording infrastructure + Chrome pixel comparison 2026-06-28 09:29:08 +00:00
Cargo.lock sprint 34: UnsafeCell→Mutex, StaleHitShared, fix seahash determinism 2026-07-01 12:29:34 +00:00
Cargo.toml Clean code: zero Rust warnings, fix canvas_diag test timeout 2026-06-28 18:07:04 +00:00
DOM-API-CHECKLIST.md Sprint 7: Differential DOM Sync + 5 DOM-Lücken geschlossen 2026-06-20 15:24:27 +00:00
libthb_html_parser.so Sprint 28.1: Mmap-backed OwnNode reads + perf bench 2026-06-24 16:12:03 +00:00
package.json Canvas recording infrastructure + Chrome pixel comparison 2026-06-28 09:29:08 +00:00
README.md Initial: Mission document + Rust workspace structure 2026-06-20 10:06:12 +00:00
SPEC-IMPLEMENTATION-AGENDA.md feat: IntersectionObserver/ResizeObserver spec tests + Canvas toBlob fix + OfflineAudioContext validation 2026-06-22 18:49:35 +00:00
SPEC-RADICAL-PERFORMANCE-PLAN.md Sprint 22.4: selector engine v2 — 19 new tests, 221/221 green 2026-06-23 21:51:11 +00:00
SPRINT-19-RENDERING-COMPLETENESS.md feat(#129): Native cascade engine — Rust FFI → JS getComputedStyle 2026-06-23 10:51:55 +00:00
SPRINT-27-MMAP-DOM.md Sprint 27: Document → MmapDomArena bridge (8/8 tests, zero-copy SetDom path) 2026-06-24 12:23:37 +00:00
SPRINT-29.0-DETAILED-PLAN.md Sprint 29.0: Detailed Plan mit allen Constraints + 19 Detection Sites + 7 Complex Sites 2026-06-25 05:12:36 +00:00
SPRINT-29.0-PHASE-7.4.md Sprint 29.0 Phase 7.4: TLS-Backend coherence fix (Chrome -> BoringSSL) 2026-06-25 06:42:20 +00:00
SPRINT-29.0-PHASE-7.md Sprint 29.0 Phase 7: Tier-Threshold fix for mutation-sync deadlock 2026-06-25 06:36:59 +00:00
SPRINT-29.5-LOCK-FREE-UDS.md Sprint 29.5: Lock-free UDS writer pipeline 2026-06-25 07:05:56 +00:00
SPRINT-29.5-SCRIPT-CACHE.md Sprint 29.5: Script-Cache + AST-Reuse (Quick-Win) 2026-06-25 07:50:30 +00:00
SPRINT-29.6-NASA-TEST-COVERAGE.md Sprint 29.6: Drop Chaos + Stress tests (YAGNI per Standards §2) 2026-06-25 09:58:37 +00:00
SPRINT-29.14-PLAN.md Sprint 29.14 plan: kill 58 MISSED mutations in direct.rs 2026-06-26 10:11:40 +00:00
SPRINT-29.15-PLAN.md Sprint 29.15 plan: TLS 1.3 cipher-order verification + mutation-score baseline + Sprint 29.16 prep 2026-06-26 11:26:21 +00:00
SPRINT-29.16-PLAN.md Sprint 29.16 plan: linkedom init-path slimming (lazy-init + type-only swap) 2026-06-26 11:29:49 +00:00
SPRINT-29.16-RESULT.md perf(sprint-29.16): type-only Node in dom-traversal + lazy-init feasibility 2026-06-26 12:30:18 +00:00
SPRINT-30.5-PLAN.md Sprint 30.5 plan: DOM-Mutation-API FFI (blocker for React/Vue-based sites) 2026-06-26 12:39:51 +00:00
SPRINT-DOM-MAX-PERF.md DOM Max Performance Plan: 6 Phasen, 32h, linkedom→MmapDomArena 2026-06-27 01:37:29 +00:00
SPRINT-MASTER-PLAN.md chore: remove temporary debug/test helper files 2026-06-27 15:23:44 +00:00
TEST_RUNS.md chore: re-enable CI runner, update test baseline 2026-06-29 19:34:25 +00:00

Rust Headless Browser

Der neue De-facto-Standard für Web Scraping.
Ein non-visueller, spec-konformer Browser — voller JS-Stack, echtes DOM,
40-50× effizienter als Headless Chrome, bei gleicher Anti-Bot-Resistenz.


Mission

Einen Browser bauen, der kein Pixel rendert aber jede Website lädt
schneller, günstiger und zuverlässiger als jeder existierende Headless Browser.

Kern-These: 80% der CPU-Zeit in Chrome/Firefox wird für Rendering,
Layout und Image-Decoding verschwendet — Dinge die kein Scraper braucht.
Durch Elimination dieser Komponenten + Rust-Arena-Allokation + Co-Prozess-Architektur
erreichen wir Faktor 40-50× Effizienzgewinn gegenüber Headless Chrome.


Architektur

┌──────────────────────────────────────────────────────────────┐
│  RUST CORE (Hauptprozess)                                    │
│                                                               │
│  ┌──────────────┐  ┌──────────────────────────────────────┐  │
│  │  Event Loop   │  │  DOM Engine                          │  │
│  │  (Tokio)      │  │  ─────────────────                   │  │
│  │               │  │  html5ever → DOM Tree (Arena)        │  │
│  │  Steuert:     │  │  selectors crate → querySelector     │  │
│  │  ├─ Timing    │  │  Event Dispatch (click, submit...)   │  │
│  │  ├─ Priorität │  │  MutationObserver in Rust            │  │
│  │  ├─ JS-Timeout│  │  DOM Snapshot → Shared Buffer        │  │
│  │  └─ Ressource │  └──────────────────────────────────────┘  │
│  │               │                                             │
│  │  ┌──────────────────────────────────────┐                  │
│  │  │  Network Stack                        │                  │
│  │  │  ─────────────────                    │                  │
│  │  │  rustls + hyper (H1/H2/H3)           │                  │
│  │  │  TLS Fingerprinting (Chrome-Level)    │                  │
│  │  │  Proxy Rotation (SOCKS5/HTTP)        │                  │
│  │  │  Cookie Jar (RFC 6265)               │                  │
│  │  │  Brotli / ZSTD Dekompression         │                  │
│  │  └──────────────────────────────────────┘                  │
│  │                                                             │
│  └──────────────────┬──────────────────────────────────────────┘
│                     │ Unix Domain Socket + Shared Memory
│                     ▼
│  ┌──────────────────────────────────────────────────────────────┐
│  │  BUN/JSC CO-PROZESS (JS Execution)                           │
│  │  ────────────────────────                                     │
│  │  JavaScriptCore (JSC) Runtime                                 │
│  │  Service Workers / Web Workers                                │
│  │  Fake Canvas 2D + WebGL (lazy emulation → Fingerprinting)    │
│  │  Fake Web Audio API                                           │
│  │  Fake Geolocation / Sensors / Battery                         │
│  │  setTimeout / setInterval / requestAnimationFrame             │
│  │  IntersectionObserver / ResizeObserver (fake)                 │
│  │  navigator.mediaDevices (fake)                                │
│  │  IndexedDB / localStorage / sessionStorage                    │
│  └──────────────────────────────────────────────────────────────┘
└─────────────────────────────────────────────────────────────────┘

Performance-Ziele vs Headless Chrome

Metrik Headless Chrome Rust Headless Browser Faktor
RAM pro Seite 150-300 MB 5-15 MB 20× weniger
DOM Parse (100KB) 15-30ms 2-4ms (html5ever) 7× schneller
querySelector(".price") ~0.5ms ~0.02ms (selectors) 25× schneller
DOM Memory (50K Nodes) ~120 MB (V8) ~3 MB (Arena) 40× weniger
Seiten/min (einfach) ~50 ~2.000+ 40× mehr
Seiten/min (SPA) ~10 ~200+ 20× mehr
Startzeit 2-5s ~50ms 50× schneller
100 parallele Seiten 15-30 GB RAM 0.5-1.5 GB RAM 20× weniger
Kosten pro 1M Seiten ~4.000€ ~100€ 40× günstiger

Anti-Bot / Fingerprinting

Technik Ansatz
TLS Fingerprint Rustls mit Chrome-Handshake + Cipher-Order + GREASE
HTTP/2 Settings Exakte Chrome-H2-Frames
TCP Timing Keine "Bot"-Latenzmuster (TCP Fast Open)
User-Agent Beliebig konfigurierbar (Chrome/Firefox/Safari)
Navigator APIs Fake WebGL, Canvas, Audio → deterministische Werte
WebDriver Flag navigator.webdriver === false
Screen/Battery Realistische Fake-Werte
JS Stack Traces Keine Rust-Frames im JS-Callstack
Proxy Chain SOCKS5 + Residential IPs

Ziel: Cloudflare, DataDome, Akamai, PerimeterX erkennen KEINEN Headless Browser.
→ Gleiche Trefferquote wie Chrome, aber zu 2% der Kosten.


Migrationspfad vom Vorgänger (true-headless-browser)

Das alte Projekt ist 2 Tage alt und enthält bereits funktionierenden Code,
der in die neue Architektur überführt wird:

Komponente Alter Status Neue Architektur
html5ever napi Funktioniert → Rust Core (direkt, ohne napi)
rustls + hyper napi Funktioniert → Rust Core (direkt, ohne napi)
DOM Implementation Happy DOM fork + OwnWindow → Rust DOM (Arena) + JSC Bridge
Canvas/WebGL/Audio Fake JS-Implementierung → Bleibt in JSC (Bun Co-Prozess)
Service Worker Bun/JSC nativ → Bleibt in JSC (Bun Co-Prozess)
Event Loop Bun/JSC nativ → Rust Tokio (Hauptschleife)
SpecProxy JS-Implementierung → Optional in JSC
DOM Snapshot Neu → Rust Shared Buffer
Batch Pipeline Neu → Rust Tokio Tasks

Projektstruktur

rust-headless-browser/
├── Cargo.toml              # Workspace
├── crates/
│   ├── core/               # Event Loop, Scheduler, Prozess-Orchestrierung
│   ├── dom/                # DOM Tree (Arena), Node, Element, Text
│   ├── html-parser/        # html5ever Wrapper → Rust DOM
│   ├── css-selectors/      # selectors crate Wrapper
│   ├── network/            # rustls + hyper H1/H2/H3, Proxy, Cookie Jar
│   ├── tls-fingerprint/    # Chrome-TLS-Handshake + GREASE
│   ├── js-bridge/          # Unix Socket + Shared Memory → Bun/JSC
│   └── scraper/            # Batch-Pipeline, DOM Snapshot, Extraktion
├── js-runtime/             # Bun/JSC Co-Prozess
│   ├── package.json
│   ├── src/
│   │   ├── index.ts         # Socket-Listener, RPC-Handler
│   │   ├── fakes/           # Canvas, WebGL, Audio, etc.
│   │   ├── workers/         # Service Worker, Web Worker Wrapper
│   │   └── bridge/          # DOM Proxy (Rust-gebundene DOM-API)
│   └── tests/
├── tests/                  # Integrationstests
│   ├── corpus/             # Testseiten (Amazon, Google, etc.)
│   └── spec/               # WPT (Web Platform Tests)
└── README.md

Roadmap

Phase 1 — Grundgerüst (Woche 1)

  • rust-headless-browser Repo erstellen
  • Rust Binary + Bun Co-Prozess Start
  • Unix Domain Socket Kommunikation
  • html5ever → DOM Tree in Arena
  • selectors crate für querySelector

Phase 2 — JS Integration (Woche 2)

  • JSC-Bridge: JS kann DOM lesen (RPC)
  • Event Dispatch (click, submit) von Rust
  • Fake Canvas/WebGL/Audio aus altem Projekt importieren
  • Service Worker + Web Worker in Bun

Phase 3 — Anti-Bot + Scraping (Woche 3)

  • TLS Fingerprinting (Chrome-Level)
  • Cookie Jar + Proxy Rotation
  • DOM Snapshot → Shared Buffer
  • Batch-Scraping Pipeline (Tokio Tasks)

Phase 4 — Korpus + Stabilität (Woche 4)

  • 100 Testseiten (Amaze, Google, Shop, SPA)
  • Cloudflare/DataDome Integrationstests
  • Performance-Benchmarks vs Chrome
  • Dokumentation + Beispiele

Prinzipien

  1. 0 Pixel. Kein Paint, kein Layout, kein Rendering.
    Alle visuellen APIs existieren (Canvas, WebGL, CSSOM) — aber sie tun nichts.

  2. Spec-konformes DOM. innerHTML, querySelector, getComputedStyle,
    Events, MutationObserver — alles nach WHATWG-Standard.

  3. Voller JS-Stack. Service Worker, Web Worker, ES Modules,
    dynamic imports — alles was Chrome kann, können wir auch.

  4. Rust bestimmt. Der Event-Loop, das Timing, die Ressourcen-Allokation —
    alles in Rust. JS ist nur ein Gast in unserer Engine.

  5. Kein Chrome-Code. Kein CDP, kein Blink, kein V8.
    Wir bauen das von Grund auf für unseren Use-Case optimiert.

  6. Batch-first. Jede Seite ist ein Tokio-Task.
    par_iter() über 1000 URLs. Kein Limit außer RAM.


Warum Rust + Bun statt Chrome/Firefox?

Chrome Firefox Rust Headless
Codebase ~25M LOC ~20M LOC ~50K LOC
DOM Memory V8 GC ~150MB SpiderMonkey ~120MB Arena ~3MB
Event-Loop V8 kontrolliert SM kontrolliert DU kontrollierst
TLS Fingerprint Patch-puppeteer Patch-selenium Native Rust
Startzeit 2-5s 1-3s ~50ms
RAM/Seite 150-300MB 100-250MB 5-15MB
Seiten/min ~50 ~40 ~2.000+
Antibut-Preis ~0.004€/Seite ~0.005€/Seite ~0.0001€/Seite

Lizenz

MIT — mach damit was du willst.