Skip to content

Rxflex/rom

Repository files navigation

ROM header

ROM

ROM architecture overview

A browser-like runtime in Rust, built without Chromium.
ROM composes an embedded JavaScript engine, browser-facing host objects, and a compatibility-driven runtime for deterministic web automation, surface emulation, and browser API research.

CI GitHub stars GitHub forks GitHub issues License

Rust 2024 edition Runtime focus Status License MIT

Why ROM

Most browser automation stacks start by shipping a full browser. ROM starts from the opposite direction:

  • keep the runtime small and programmable
  • emulate the browser surface incrementally
  • validate compatibility against browser-facing probes and real harnesses
  • stay transparent enough that the runtime can be inspected, extended, and reasoned about

The result is a native Rust workspace that aims to feel browser-like at the API layer without inheriting the operational weight of Chromium.

What ROM Is

  • A Rust workspace with a lightweight embedded JavaScript engine.
  • A growing browser API compatibility layer.
  • A runtime designed around deterministic probes, snapshots, and acceptance harnesses.
  • A Rust core with JS and Python bindings that can use either native extensions or the CLI bridge.

What ROM Is Not

  • Not a full browser engine.
  • Not a layout engine or Chromium replacement.
  • Not production-complete yet.
  • Not claiming full Web Platform coverage.

Highlights

Area Current State
Runtime core Embedded JavaScript runtime lifecycle, script execution, error handling
Web platform fetch, streams, blobs, files, URLs, parser, workers, messaging, cookies, SSE, WebSocket
Crypto digest, HMAC, AES-CTR, AES-CBC, AES-GCM, AES-KW, PBKDF2, HKDF
Validation Browser-like parameter validation, JWK validation, key usage validation, import/export edge handling
Compatibility surface_snapshot(), fingerprint_probe(), vendored FingerprintJS harness, browser reference runner
Media and device surface permissions, media devices, plugins, mime types, viewport, orientation, media queries

Browser Surface Snapshot

Networking and data

  • fetch
  • Headers, Request, Response
  • ReadableStream-based Request.body and Response.body
  • redirect modes: follow, error, manual
  • CORS response gating and preflight validation
  • AbortController, AbortSignal
  • Blob, File, FormData
  • URL, URLSearchParams, URLPattern
  • DOMParser
  • blob: object URLs
  • cookies via document.cookie, Cookie, and Set-Cookie

Realtime and messaging

  • MessageEvent, MessagePort, MessageChannel
  • BroadcastChannel
  • Worker with Blob URL scripts, postMessage(), and importScripts()
  • EventSource with retry, reconnect, custom events, lastEventId, and close()
  • WebSocket with ws: and wss:, text and binary frames, Blob payloads, and close events

Crypto

  • crypto.getRandomValues()
  • crypto.randomUUID()
  • crypto.subtle.digest() for SHA-1, SHA-256, SHA-384, SHA-512
  • HMAC generateKey(), importKey(), exportKey(), sign(), verify()
  • AES-CTR, AES-CBC, AES-GCM generateKey(), importKey(), exportKey(), encrypt(), decrypt()
  • AES-GCM 128/192/256-bit keys and tag lengths 96..128
  • AES-KW wrapping flows
  • PBKDF2 and HKDF for importKey(), deriveBits(), deriveKey()
  • browser-like secret-key validation for length, usages, params, JWK content, import/export, wrap/unwrap payloads, and derive semantics

DOM and compatibility surface

  • structuredClone()
  • FileReader
  • navigator.permissions.query()
  • navigator.mediaDevices
  • navigator.userAgentData
  • navigator.plugins, navigator.mimeTypes, navigator.pdfViewerEnabled
  • viewport globals, visualViewport, screen.orientation, matchMedia()
  • MutationObserver, ResizeObserver, IntersectionObserver
  • DOM event propagation with capture, bubble, once, propagation stopping, and composedPath()

Architecture

ROM compatibility workflow

The workspace is intentionally split into three layers:

  • crates/rom-core Raw embedded JavaScript engine wrapper.
  • crates/rom-webapi Browser API bootstrap and compatibility shims.
  • crates/rom-runtime High-level environment assembly that composes engine and Web API behavior.

This separation keeps the core small, the web surface modular, and the runtime acceptance-focused.

Quick Start

Install the published bindings

npm install @rxflex/rom
pip install rom-runtime

Published packages:

If you want package-specific usage examples, see:

Runtime defaults

  • cors_enabled is false by default, so cross-origin fetch() is direct by default instead of browser-blocked.
  • proxy_url is optional and supports http://, socks5://, and socks5h://.
  • cookie_store is optional, but the Node.js and Python wrappers now update it automatically so cookies survive separate bridge-backed calls.
  • For convenience, the Node.js and Python wrappers also accept cookie_store as a raw cookie header string and a cookies alias with string/object/array inputs, then normalize it into ROM's serialized cookie store.
  • local_storage and session_storage are optional and accept serialized JSON objects, JS/Python maps, or entry arrays in the wrappers; updated values are synced back into wrapper config after each call.
  • referrer is optional if you need document.referrer to match an upstream page.
  • Native Node.js and Python bindings keep one live runtime per RomRuntime instance, so globals, cookies, and storage created in one eval() call remain available to the next call.
  • The default navigator surface is Chrome-like rather than ROM-branded, including navigator.userAgent, navigator.vendor, and navigator.userAgentData.

Build

cargo build

Run the full Rust test suite

cargo test

Use the CLI bridge directly

echo "{\"command\":\"surface-snapshot\"}" | cargo run -p rom-runtime --bin rom_bridge

Use the Node.js wrapper

import { RomRuntime, hasNativeBinding } from "@rxflex/rom";

const runtime = new RomRuntime({
  href: "https://example.test/",
  cors_enabled: false,
  proxy_url: process.env.ROM_PROXY_URL ?? null,
});

const result = await runtime.evalAsync(`
  (async () => {
    document.cookie = "seed=1; path=/";
    const response = await fetch("https://example.test/data");
    return JSON.stringify({
      href: location.href,
      status: response.status,
      body: await response.text(),
      cookie: document.cookie,
    });
  })()
`);

console.log("native binding:", hasNativeBinding());
console.log(JSON.parse(result));

await runtime.evalAsync(`
  (async () => {
    await fetch("https://example.test/next");
    return document.cookie;
  })()
`);

console.log("persisted cookie store:", Boolean(runtime.config.cookie_store));

Optional native build:

cd bindings/gom-node
npm run build:native

Use the Python wrapper

from rom import RomRuntime, has_native_binding

runtime = RomRuntime(
    {
        "href": "https://example.test/",
        "cors_enabled": False,
        "proxy_url": None,
    }
)

print("native binding:", has_native_binding())

result = runtime.eval_async(
    """
    (async () => {
      document.cookie = "seed=1; path=/";
      const response = await fetch("https://example.test/data");
      return JSON.stringify({
        href: location.href,
        status: response.status,
        body: await response.text(),
        cookie: document.cookie,
      });
    })()
    """
)

print(result)

runtime.eval_async(
    """
    (async () => {
      await fetch("https://example.test/next");
      return document.cookie;
    })()
    """
)

print("persisted cookie store:", bool(runtime.config.get("cookie_store")))

Optional native build:

python -m pip install maturin
python -m maturin develop --manifest-path bindings/gom-python/Cargo.toml

Run the browser reference harness

npm install
npx playwright install chromium
npm run fingerprintjs:browser-reference

Compatibility Strategy

ROM does not treat compatibility as a vague goal. It already has two concrete acceptance layers:

  • internal structured probes via RomRuntime::surface_snapshot() and RomRuntime::fingerprint_probe()
  • a vendored FingerprintJS harness via RomRuntime::run_fingerprintjs_harness()

That gives the project a measurable loop instead of an anecdotal one.

Roadmap Direction

  • push deeper Web Platform coverage without losing runtime clarity
  • improve long-lived networking and worker fidelity
  • keep tightening browser-like exception and validation behavior
  • expand reference-driven compatibility checks
  • strengthen the native JS/Python binding story on top of the shared bridge protocol

Repository Map

.
├── bindings/
│   ├── gom-node
│   └── gom-python
├── crates/
│   ├── rom-core
│   ├── rom-runtime
│   └── rom-webapi
├── docs/
├── fixtures/
└── tools/

Open Source Notes

ROM is experimental, but it is being built in the open with a clear technical direction. If you care about browser emulation, deterministic runtime design, anti-bot research tooling, or compatibility-first Web API implementation, this repo is meant to be inspectable and hackable.

Issues, design discussion, and focused contributions are welcome. Start with CONTRIBUTING.md and use SECURITY.md for vulnerability reports.

License

MIT. See LICENSE.

About

A browser-like runtime in Rust, built without Chromium. ROM composes an embedded JavaScript engine, browser-facing host objects, and a compatibility-driven runtime for deterministic web automation, surface emulation, and browser API research.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors