Run any site's JavaScript from Python.

A new-generation headless browser built on Firefox internals. The authentic SpiderMonkey engine and Necko HTTP stack, with no window and no renderer — made for web scraping, JS reverse engineering, data collection, and getting past bot checks.

python -m pip install ruyijs
Windows x64 · Python 3.10+ · v0.1.6 · SpiderMonkey Firefox 158 · Necko HTTP/1.1·2·3
session.py
from ruyijs import Context

with Context() as ctx:
    ctx.configure_fingerprint({
        "navigator": {"language": "zh-CN"},
        "locale": {"timezone": "Asia/Shanghai"},
    })
    ctx.load_page("https://target.example/", html)
    # run the site's own JS to mint the token
    token = ctx.eval("window.__sign(payload)")
    print(token)  # → verified ✓

SpiderMonkey

The real Firefox JS engine — no reimplementation

Necko

Native HTTP/1.1 · 2 · 3 transport, per-context proxy

38+

Bounded browser contexts: DOM, Workers, Canvas…

0px

No window, no renderer — pure JS + Web API, fast

WHY RUYIJS

Firefox internals, not a browser impersonation.

Headless Chrome ships a GPU-rendering, window-managing process that vendors have spent years learning to detect. ruyiJS embeds only the internals that matter for automation.

Authentic engine

Genuine SpiderMonkey (Firefox 158) and the Necko network stack — the same bytecode, timers, and TLS fingerprint a real browser emits.

Configurable fingerprint

Set Navigator, Screen, viewport, timezone, and locale through one validated profile surface before the first page script runs.

Per-context isolation

Each Context is its own process with a persistent JavaScript world and its own proxy, so sessions stay isolated and reproducible.

Deterministic clock

Drive timers with a logical clock for perfectly reproducible runs, or switch to the system clock for live network work.

Native fetch over Necko

In-page fetch and XHR ride real HTTP/1.1, 2 and 3. Serve captured responses with put_resource() to replay whole flows offline.

Python ↔ JS bridge

Pass data with set(), call JS functions from Python, and expose Python callbacks to the running script. Workers, Service Workers, and iframes included.

PROVEN IN THE FIELD

Verification systems it defeats.

Every example drives the site's own JavaScript to produce the parameters it demands, then completes the flow end to end. Ships runnable in the package: python -m ruyijs.examples <name>.

Strictly prohibited for any unlawful use — provided solely for research into a new generation of AI browsers.

FROM PYTHON

Scriptable, with no window in sight.

Call Python from JavaScript
with Context() as ctx:
    ctx.expose(lambda a, b: a + b, "add")
    print(ctx.eval("add(20, 22)"))  # 42
Fetch through a per-context proxy
with Context(proxy="http://127.0.0.1:7890") as ctx:
    ctx.load_page("https://example.com/", "")
    ctx.eval("fetch('/api').then(r => r.json())")
    ctx.advance(25)  # drive the event loop
Load a page offline and query the DOM
with Context() as ctx:
    ctx.put_resource(".../app.js", "window.answer=42")
    ctx.load_page(url, "<script src=/app.js></script>")
    ctx.eval("document.title")
Catch JavaScript errors as Python exceptions
from ruyijs import Context, JSError
try:
    ctx.eval("throw new TypeError('bad')")
except JSError as e:
    print(e.name, e.stack)

CONTACT

Get in touch.

Questions, permission requests, commercial licensing, or just to talk shop — add the author on WeChat, or scan to join the discussion group.

WeChat 如意 WeChat: 如意 Author · Licensing · Tech
AI 浏览器过检测交流群 Discussion Group AI 浏览器过检测交流群

The group QR refreshes periodically; if expired, add the author on WeChat (如意) for an invite.

Install it. Point it at the hard target.

One pip install ships the pinned Firefox runtime. No browser download, no window, no telemetry.

python -m pip install ruyijs