Skip to main content

Run JavaScript with full browser APIs in Python, powered by V8

Project description

iv8 — Run JavaScript with a Full Browser Environment in Python

中文 | English

PyPI Python Platform GitHub

iv8 is a high-performance Python native extension built on the V8 engine. It implements browser APIs at the C++ level, providing highly controllable, high-fidelity BOM/DOM/CSSOM emulation with built-in API call chain monitoring and Chrome DevTools remote debugging. Run JavaScript that depends on a web environment directly in Python — no browser required.

Suitable for browser environment emulation, automated script execution, security research, JS engine testing, and more.

This repository is the Community Edition of iv8, offering a fully functional baseline browser environment emulation that covers the vast majority of everyday use cases.

iv8 also offers a Pro Edition, which adds a CSS layout engine (cascade, inheritance, box model layout), CSS animation and transition drivers, a protocol stack built by deep-trimming Chromium's network module (not a Cronet wrapper), multi-context Worker parallel execution, enhanced API semantic/timing/boundary alignment (covering more spec edge cases), and deep algorithmic optimizations for computation performance and memory footprint. The Community Edition continues to evolve, and mature Pro features will progressively be backported.

The Python–V8 interop layer draws on the design of STPyV8, with optimized design and implementation.


Key Highlights

Feature Description
C++ Native Browser APIs Pure C++ implementation of BOM / DOM / CSSOM / Events / Crypto / Canvas / WebGL and more, covering 70+ HTML elements, 25+ CSS rule types, 80+ event types
Streaming HTML Parser page.load aligns with browser navigation flow: HTML parsing → <script> pause & execute → stylesheet processing → DOMContentLoaded / load event dispatch
Programmable Event Loop Micro/macro-task tiered scheduling (aligned with HTML spec); sleep(5000) completes instantly in logical time mode
Browser Fingerprint Config Ships with Chrome/Windows default fingerprint (200+ fields); selectively override via environment, JS-side behavior matches real browsers
Multi-thread Parallelism Each Context owns a V8 Isolate; GIL released during execution; ~4.7x speedup measured with 8 threads
DevTools Remote Debugging Breakpoints, API access breakpoints, Elements / Application panels; built-in anti-debug protection (debugger; disabled)
API Monitoring Debug mode auto-records browser API access chains and JS built-in reflection paths to locate environment probing logic
Trusted Input Events Dispatches isTrusted=true mouse / pointer events (click / mousedown / pointerdown, etc.)
Function Disguise wrapNative disguises JS functions as [native code], reducing observable differences introduced by local patches

Architecture Overview

iv8 free System-level Runtime Model

Python enters the C++ Bridge through JSContext, each Context owns a dedicated v8::Isolate enabling true parallelism across multiple Python threads; within the isolate, the window scope and per-document runtime are mounted, with core capabilities including the page.load loading flow, event loop and time control, offline resource model, and trusted input; monitoring and debugging form an optional debug plane, activated only in debug / with_devtools() mode.

Quick Start

pip install --upgrade iv8 -i https://pypi.org/simple

We recommend installing or upgrading from the official PyPI index. Some third-party mirrors may lag behind and may not have the latest release immediately.

Supports Python 3.9 – 3.14, Windows (x64), and Linux (x64). The Linux build is compiled to the manylinux standard and runs on CentOS, Ubuntu, Debian, Fedora, and other mainstream distributions.

macOS (experimental): a prebuilt wheel for macOS Apple Silicon (arm64) is now available, for Python 3.11–3.14 and macOS 14+. It is distributed via GitHub Releases and is not published to PyPI. The author has no macOS device for long-term testing, so this is a community/experimental build (it passes the offline comprehensive API self-test, 173/173); feedback is welcome. To install, download the wheel from Releases and run pip install ./iv8-0.1.3-cp314-cp314-macosx_14_0_arm64.whl.

import iv8

with iv8.JSContext() as ctx:
    # Execute JavaScript
    print(ctx.eval("1 + 2"))  # 3

    # Browser APIs work out of the box
    print(ctx.eval("navigator.userAgent"))   # Mozilla/5.0 ...
    print(ctx.eval("navigator.webdriver"))   # False

    # Load an HTML page (streaming parse + script execution + event dispatch)
    ctx.eval("""
        window.__iv8__.page.load({
            baseURL: 'https://example.com',
            html: '<html><body><div id="app">Hello</div></body></html>'
        });
    """)
    print(ctx.eval("document.getElementById('app').textContent"))  # "Hello"

Performance Characteristics

The following data was measured on Intel Core i7-14700 / Windows 10 / Python 3.11; results may vary on different hardware.

Dimension Metric Data
Speed JSContext create + eval + destroy ~3.3 ms / call
Simple eval throughput (1+1) ~950,000 ops/s
Browser API calls (navigator / DOM / crypto) 340,000 – 570,000 ops/s
Real webpage DOM parse (Wikipedia JavaScript article, ~440 KB) ~7 ms / page (incl. Context create+destroy ~11.5 ms, serial ~86 pages/s)
Memory First load (import iv8 + 1st Context) +15 MB
Per-round peak increment (batch loop) ~9 MB
100-round long-run cumulative drift +2 MB
Multi-thread Speedup (2 / 4 / 8 threads) 1.86x / 3.26x / 4.71x

Memory figures are iv8 marginal increments (excluding the Python interpreter itself). Multi-thread test uses compute-intensive JS (200K sin/cos loop iterations); real-world scenarios (executing hundreds of KB of obfuscated JS) typically show better speedup. For GIL release mechanism, Context creation overhead, and page.load vs innerHTML guidance, see the Best Practices section below.


Browser API Compatibility

iv8 provides an extensive browser API emulation layer on top of the V8 engine, covering the following web standards (some are interface-level stubs):

Category Coverage
DOM & HTML Document, Element, Node inheritance chain, 70+ HTML element interfaces, ShadowRoot, MutationObserver, Range, Custom Elements, etc.
SVG SVGElement inheritance chain with 50+ SVG element interfaces, SVGAnimated* series
CSS & CSSOM CSSStyleSheet, 25+ CSSRule subclasses, CSSStyleDeclaration, CSS Typed OM (CSSUnitValue / CSSMath*), Highlight API
Event System EventTarget / Event inheritance chain, 80+ event types (UI / Mouse / Pointer / Keyboard / Touch / Drag / Clipboard / Animation, etc.)
Window & Navigator Window, Location, History, Navigator, Screen, Performance API, Navigation API
Network XMLHttpRequest, Fetch API (Request / Response / Headers), Streams, WebSocket, WebTransport, Beacon. The Community Edition does not include a built-in real HTTP/HTTPS transport; XHR / fetch / external resources receive responses via add_resource or page.load.resources, giving users full control over real request details (proxy / TLS fingerprint / cookie pool)
Encoding & File TextEncoder / Decoder, Blob, File, FileReader, URL / URLSearchParams, File System Access
Storage localStorage, sessionStorage, CookieStore, IndexedDB, Storage Buckets
Crypto crypto.getRandomValues, SubtleCrypto (AES-GCM / AES-CBC / RSA-OAEP / RSA-PSS / ECDH / ECDSA / HMAC / HKDF / PBKDF2 / digest algorithms, etc.)
Canvas & Graphics Canvas 2D, WebGL / WebGL2 (30+ extensions, parameters from environment.webgl.*), WebGPU, OffscreenCanvas
Media HTMLMediaElement, Web Audio API (20+ AudioNode subclasses), MediaStream, WebRTC, WebCodecs
Timers & Scheduling setTimeout / setInterval / requestAnimationFrame / requestIdleCallback, Scheduler API
Web Animations Animation, KeyframeEffect, DocumentTimeline, ScrollTimeline, ViewTimeline
Geometry DOMPoint, DOMRect, DOMQuad, DOMMatrix and ReadOnly variants
Performance PerformanceTiming, PerformanceResourceTiming, PerformanceObserver, MemoryInfo, etc.
Permissions & Security Permissions API, Credential Management, Trusted Types, CSP
Device APIs Clipboard, Notification, Geolocation, DeviceOrientation, Sensor API, BatteryManager
Communication MessagePort, Web MIDI, Presentation API
Workers Worker / SharedWorker / ServiceWorker / Worklet

Feature Details

1. JavaScript Execution & Type Conversion

Built on the modern V8 engine with full ES6+ syntax support (class, modules, Promise, async/await, optional chaining, private fields, top-level await, etc.). Return values are automatically converted to Python types.

with iv8.JSContext() as ctx:
    # Primitive types auto-convert
    print(ctx.eval("42"))                    # int: 42
    print(ctx.eval("'hello'"))               # str: "hello"
    print(ctx.eval("[1, 2, 3]"))             # list: [1, 2, 3]

    # to_py=True recursively converts complex nested objects
    data = ctx.eval("({name: 'test', items: [1,2,3]})", to_py=True)
    print(data['items'])  # [1, 2, 3]

    # Full ES6+ support
    ctx.eval("""
        const { name, scores } = { name: 'Alice', scores: [90, 85, 92] };
        var avg = scores.reduce((a, b) => a + b, 0) / scores.length;
    """)
    print(ctx.eval("avg"))  # 89

2. Browser Environment & Fingerprint Configuration

iv8 ships with a complete Chrome desktop / Windows baseline fingerprint (200+ fields) — ready to use without passing environment. Use the environment dict to selectively override fingerprint fields; unspecified fields retain their defaults. The exposed browser version is determined by navigator.userAgent / navigator.userAgentData fields, freely overridable by users — built-in defaults serve only as out-of-the-box fallbacks and do not constitute a commitment to a specific Chrome version.

with iv8.JSContext(environment={
    "navigator": {
        "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
        "platform": "Win32",
        "language": "zh-CN",
        "languages": ["zh-CN", "en-US"],
        "hardwareConcurrency": 8,
        "deviceMemory": 8,
    },
    "screen": {
        "width": 1920, "height": 1080, "colorDepth": 24,
    },
    "location": {
        "href": "https://example.com/page",
    },
    "webgl": {
        "vendor": "Google Inc. (NVIDIA)",
        "renderer": "ANGLE (NVIDIA, NVIDIA GeForce RTX 3060)",
    },
}) as ctx:
    print(ctx.eval("navigator.userAgent"))
    print(ctx.eval("navigator.hardwareConcurrency"))  # 8
    print(ctx.eval("screen.width"))                    # 1920

View all configurable fields: get_defaults() returns all supported paths and their default values, making it easy to discover the full override surface:

for path, value in sorted(iv8.JSContext.get_defaults().items()):
    print(f"{path} = {value!r}")
# navigator.userAgent = 'Mozilla/5.0 ...'
# screen.width = 1920
# window.devicePixelRatio = 1.0
# ...

3. DOM Manipulation & Page Loading

Full DOM engine with HTML streaming parse, element creation, and node manipulation.

Two ways to load HTML:

  • page.load(snapshot) — Streaming load aligned with key browser navigation stages: parse HTML by chunk, pause on <script> for execution (including external resources from the bundle), process <style> and <link> stylesheets, dispatch DOMContentLoaded / load events, sync document.URL / location.href. Best for scenarios requiring script execution, lifecycle events, or simulating a real page load.

  • document.documentElement.innerHTML — Direct assignment that only builds the DOM tree — no script execution, no event dispatch, no URL synchronization. Lower overhead, ideal for simple scenarios where only the DOM structure is needed (e.g., parsing HTML, extracting data).

page.load(snapshot) parameters:

Field Type Required Description
baseURL string Yes Page URL, synced to document.URL and location.href
html string Yes HTML source
resources Object No External resource mapping (URL → content); <script src> / <link href> in HTML and runtime XHR / fetch all match against this
headers Object/Array No Main document response headers (CSP, Set-Cookie, etc.)

resources format: Keyed by URL; values support shorthand and full format:

resources: {
    // Shorthand: value is the content string directly
    'https://example.com/lib.js': 'var LIB = true;',

    // Full format: specify HTTP status, response headers, body
    'https://example.com/app.js': {
        body: 'var APP = true;',
        status: 200,
        headers: [['content-type', 'application/javascript']],
    }
}
with iv8.JSContext() as ctx:
    ctx.eval("""
        window.__iv8__.page.load({
            baseURL: 'https://example.com',
            html: '<html><head><script src="/app.js"></script></head><body></body></html>',
            resources: {
                'https://example.com/app.js': { body: 'window.APP_LOADED = true;' }
            }
        });
    """)
    print(ctx.eval("window.APP_LOADED"))  # True

4. Event Loop & Timer Control

Implements micro-task / macro-task two-phase scheduling (aligned with HTML spec event loop), with macro-tasks prioritized by level and fine-grained time control APIs.

  • Macro-tasks: setTimeout, setInterval, requestAnimationFrame, XHR/fetch callbacks, etc.
  • Micro-tasks: Promise.then/catch/finally, queueMicrotask, MutationObserver callbacks, etc.
with iv8.JSContext(time_mode="logical") as ctx:
    ctx.eval("""
        var log = [];
        setTimeout(() => log.push('macro-100'), 100);
        setTimeout(() => log.push('macro-200'), 200);
        Promise.resolve().then(() => log.push('micro'));
        queueMicrotask(() => log.push('micro-2'));
    """)

    ctx.eval("window.__iv8__.eventLoop.advance(250)")
    print(ctx.eval("log"))
    # ['micro', 'micro-2', 'macro-100', 'macro-200']

Event loop control methods:

Method Description
advance(total, step?) Advance virtual time frame-by-frame (default step ~16.67ms), simulating rAF rhythm
sleep(ms?, max?) Advance virtual time by ms milliseconds, draining the task queue in chronological order
tick(ms?) Advance ms milliseconds and run one event loop iteration
drain(max?) Drain all due tasks without advancing time
drainMicrotasks() Drain only the micro-task queue
drainTimers() Process only due timer callbacks
setAutoAdvanceStep(ms) Set the auto-increment step for performance.now() (default 0.001ms)
setDateAdvanceStep(ms) Set the auto-increment step for Date.now() (default 1ms)

Time modes:

Mode Description Use Case
logical (default) Pure logical advancement; sleep(5000) completes instantly Automation, fast execution
system Anchored to system time; Date.now() reflects real elapsed time during JS execution Time-sensitive scenarios (PoW, time-delta checks)

5. Network Request Interception

Community Edition network boundary: The Community Edition does not directly send real HTTP/HTTPS requests and does not include the Chromium network transport stack. XHR / fetch / external resources match responses from the offline bundle by default; real requests should be performed by the user's Python HTTP client and then injected via add_resource() or page.load.resources. The Pro Edition provides a real protocol stack built from a deeply trimmed Chromium net module.

add_resource() and the resources parameter of page.load write into the same offline resource bundle. During HTML parsing, <script src> / <link href> / CSS @import, as well as runtime XHR / fetch, all match against this bundle. netLog automatically records all XHR / fetch / navigation requests initiated from the JS side, enabling analysis of the target JS network behavior.

with iv8.JSContext() as ctx:
    ctx.eval("""
        window.__iv8__.page.load({
            baseURL: 'https://example.com',
            html: '<html><body></body></html>'
        });
    """)

    # XHR requests are automatically captured by netLog
    ctx.eval("""
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'https://api.example.com/data', false);
        xhr.send();
    """)
    print(ctx.eval("xhr.status"))  # 200

    entries = ctx.eval("window.__iv8__.netLog.entries", to_py=True)
    for entry in entries:
        print(f"  {entry.get('method', '')} {entry.get('url', '')}")

Collaborating with real HTTP requests: iv8's network APIs do not send HTTP requests directly; instead they match responses from the offline bundle. This design gives users full control over the network layer (proxy, TLS fingerprint, cookie pool, etc., are all determined by the user's HTTP client). Typical workflow: JS initiates request → pause event loop → Python sends real HTTP request → inject response → resume event loop.

import requests

with iv8.JSContext() as ctx:
    ctx.eval("""
        window.__iv8__.page.load({
            baseURL: 'https://example.com',
            html: '<html><body></body></html>'
        });
    """)

    # JS initiates an async XHR
    ctx.eval("""
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'https://api.example.com/data');
        xhr.onload = function() { window._result = xhr.responseText; };
        xhr.send();
    """)

    # Python sends the real request and injects the response into the offline bundle
    resp = requests.get("https://api.example.com/data")
    ctx.add_resource(
        url="https://api.example.com/data",
        body=resp.text,
        status=resp.status_code,
        headers=dict(resp.headers),
    )

    # Resume the event loop — the XHR callback will match the just-injected resource
    ctx.eval("window.__iv8__.eventLoop.drain()")
    print(ctx.eval("window._result"))

6. Monitoring & Debugging

Runtime modes:

Mode Description
prod (default) Zero monitoring overhead, suitable for production use
debug Enables API call chain tracing, reflection interceptor monitoring, and DevTools debugging

API monitoring in debug mode: Automatically records all monitored browser API property reads/writes, method calls, and constructor calls (high-frequency built-in types like Math / JSON / Array / typed arrays are silenced by default to reduce noise; adjustable via ignore_apis). Also instruments JS built-in reflection paths (Object.keys / getOwnPropertyDescriptor / defineProperty, Reflect.ownKeys / get / has, Function.prototype.toString, JSON.parse / stringify, etc.), recording the target JS environment probing chain.

DevTools debugging: Built-in Chrome DevTools Protocol (CDP) support.

Anti-debug Protection & Replacement Tools:

  • debugger;vdebugger;: iv8 disables native debugger; statements (they won't trigger breakpoints) because target JS commonly exploits infinite debugger loops for anti-debugging. Use vdebugger; instead — its behavior is identical to standard debugger.
  • consolevconsole: Some anti-scraping JS detects the debugging environment through behavioral differences in the console API. After setting enable_console=False to disable standard console DevTools reporting, use vconsole.log() / vconsole.warn() etc. as replacements. vconsole output appears only in the DevTools Console panel and is completely invisible to target JS.
# Basic debugging
with iv8.JSContext(mode='debug').with_devtools(port=9229) as ctx:
    ctx.eval("vdebugger;")  # Pauses in Chrome DevTools

# API access breakpoints + covert debug channel
with iv8.JSContext(mode='debug').with_devtools(
    port=9229,
    watch_apis=["navigator.userAgent", "document.cookie", "canvas.toDataURL"],
    enable_console=False,
) as ctx:
    ctx.eval("let ua = navigator.userAgent;")  # Triggers breakpoint
    ctx.eval("vconsole.log('debug info', ua);")  # Only visible in DevTools

Supported DevTools features: Breakpoint debugging (vdebugger;), API access breakpoints (watch_apis), event listener breakpoints, XHR/Fetch URL breakpoints, DOM element structure inspection (Elements panel), Cookie / Storage inspection and editing (Application panel), step-through execution, variable inspection and modification.

7. Input Event Simulation

Dispatches trusted mouse / pointer events with isTrusted=true; capture → target → bubble chain and isTrusted semantics aligned with Chrome.

with iv8.JSContext() as ctx:
    ctx.eval("""
        window.__iv8__.page.load({
            baseURL: 'https://example.com',
            html: '<html><body><button id="btn">Click</button></body></html>'
        });

        var clicked = false;
        document.getElementById('btn').addEventListener('click', e => {
            clicked = e.isTrusted;  // true
        });

        window.__iv8__.input.dispatchMouseEvent({
            type: 'click',
            target: document.getElementById('btn'),
            clientX: 50, clientY: 25,
            button: 0, buttons: 0
        });
    """)
    print(ctx.eval("clicked"))  # True

8. Function Disguise

with iv8.JSContext() as ctx:
    ctx.eval("""
        var myFunc = window.__iv8__.wrapNative(function(x) { return x * 2; }, 'myFunc');
    """)
    print(ctx.eval("myFunc.toString()"))     # "function myFunc() { [native code] }"
    print(ctx.eval("myFunc(21)"))            # 42

9. Python ↔ JS Interop

expose() exposes Python objects to the __iv8__.data namespace in JS, without polluting the window global scope. When JS calls an exposed Python function, the GIL is automatically acquired (blocking the current V8 execution and other Python threads), so exposed functions should be kept lightweight.

import requests

with iv8.JSContext() as ctx:
    # Method 1: Named expose
    ctx.expose(requests.get, "httpGet")
    # JS: __iv8__.data.httpGet("https://...")

    # Method 2: Auto-named (uses the function's __name__ attribute)
    def fetch_data(url):
        return requests.get(url).text
    ctx.expose(fetch_data)
    # JS: __iv8__.data.fetch_data("https://...")

    # Method 3: Keyword argument batch expose
    ctx.expose(get=requests.get, post=requests.post)
    # JS: __iv8__.data.get(...), __iv8__.data.post(...)

    # Expose non-function data (dicts, lists, etc.)
    ctx.expose({"token": "abc123", "debug": True}, "config")
    result = ctx.eval("__iv8__.data.config.token")  # "abc123"

Python API Reference

iv8.JSContext

Main entry class. Creates an independent V8 context with browser APIs.

Constructor parameters:

Parameter Type Default Description
mode str "prod" "prod" production mode / "debug" debug mode
environment dict None Browser fingerprint configuration (navigator / screen / location / webgl, etc.)
config dict None Framework behavior configuration (timezone, permissions.*, etc.; full paths via get_defaults())
ignore_apis list Built-in default APIs to exclude from monitoring logs
time_mode str "logical" "logical" logical time / "system" system time
js_api str "__iv8__" JS-side utility object mount name

Methods:

Method Description
eval(source, name="", line=-1, col=-1, to_py=False, devtools=True) Execute JS code; return value auto-converts to Python types
close(gc="none") Release the context. gc can be "low_memory" (or "v8" / True) / "aggressive" to trigger GC
add_resource(url, body, status=200, headers=None) Inject an offline HTTP response
with_devtools(port=9229, watch_apis=None, enable_console=True) Enable DevTools debugging
expose(obj, name?) / expose(**kwargs) Expose Python objects to the __iv8__.data namespace
get_defaults() Get all supported environment/config paths and their default values

Context manager usage (recommended):

with iv8.JSContext() as ctx:
    ctx.eval("...")
# Resources automatically released

JS-side Utility Object

When a context is created, iv8 mounts a utility object window.__iv8__ on the global scope (customizable via the js_api parameter). This object is designed to be "undetectable" (typeof window.__iv8__ === "undefined") and does not affect target JS behavior.

Utility Description
__iv8__.eventLoop.* Event loop control (advance / sleep / tick / drain, etc.)
__iv8__.page.load(snapshot) Stream-load an HTML document
__iv8__.input.dispatchMouseEvent(init) Dispatch trusted mouse events (isTrusted=true)
__iv8__.input.dispatchPointerEvent(init) Dispatch trusted pointer events
__iv8__.netLog.entries Captured network request log array
__iv8__.wrapNative(fn, name) Disguise a JS function as a native function
__iv8__.help() Print all available utilities and descriptions

Best Practices

GIL & Multi-threading

iv8 releases the Python GIL during V8 JavaScript execution, allowing multiple threads to truly execute JS code in parallel. When V8 calls back into Python (e.g., a function exposed via expose() is invoked by JS), the GIL is automatically reacquired.

Python eval() → Release GIL → V8 executes → (JS calls Python → Acquire GIL → Execute → Release GIL) → V8 returns → Acquire GIL → Return to Python

Each JSContext owns an independent V8 Isolate — no additional locking required for multi-threaded use:

import threading

def run_js(thread_id, environment):
    with iv8.JSContext(environment=environment) as ctx:
        ua = ctx.eval("navigator.userAgent")
        print(f"Thread {thread_id}: {ua}")

threads = []
for i in range(4):
    t = threading.Thread(target=run_js, args=(i, {
        "navigator": {"userAgent": f"ThreadBot/{i}"}
    }))
    threads.append(t)
    t.start()
for t in threads:
    t.join()

Since the GIL is released during V8 execution, multi-threading achieves near-multiprocess parallelism while avoiding the overhead of inter-process communication and memory copying. For scenarios requiring simultaneous execution of multiple JS environments (e.g., concurrently running scripts from different sites), prefer multi-threading.

Context Creation Overhead

JSContext creation (including an independent V8 Isolate + browser API surface) and destruction are lightweight — approximately 3ms per cycle (~300 ctx/s) in practice. There is no need to aggressively reuse contexts. Creating a fresh JSContext each time provides a clean environment state, avoiding side-effect contamination from previous executions.

page.load vs innerHTML

Approach Overhead Use Case
page.load(snapshot) Higher: streaming parse + script execution + event dispatch When full page lifecycle is needed (script execution, event triggering)
innerHTML = html Lower: builds DOM tree only When only DOM structure is needed (parsing HTML, extracting data)

If the target JS does not depend on DOMContentLoaded / load events or external script execution, using innerHTML assignment can significantly reduce overhead.


Changelog

0.1.3

  • Fixed overly strict Latin1 validation in btoa(), so inputs such as String.fromCharCode(0xE9) now encode correctly.
  • Fixed a DevTools local debugging issue where localhost could resolve to IPv6 on some Windows / Chrome environments and cause the WebSocket connection to disconnect.
  • Improved parser-time document.write() behavior in page.load(), so DOM written by inline scripts is now persisted in the document tree.
  • Fixed innerHTML serialization only returning the first child node; it now serializes all child nodes in order.
  • Added a prebuilt macOS Apple Silicon wheel (arm64 / Python 3.11–3.14), an experimental build distributed via GitHub Releases (not on PyPI); passes the offline comprehensive API self-test (173/173).

License

The iv8 Community Edition is currently distributed as pre-compiled binaries. Browser-environment emulation is an ongoing process of behavioral alignment and adversarial iteration; opening the full implementation too early may make it easier to build targeted detections. As the project becomes more refined and its interfaces and behaviors stabilize, we will evaluate gradually opening more implementation details or source code in the future.

  • Free for personal, educational, and non-commercial use
  • Reverse-engineering, decompilation, and disassembly are prohibited
  • Commercial use (integration into commercial products or services) requires a commercial license (Pro Edition)
  • Unauthorized redistribution is prohibited

See the LICENSE file for details.

Disclaimer

This project is intended solely for learning, research, security testing, and lawful automation purposes. Users must comply with the terms of service and robots policies of target websites, as well as all applicable laws and regulations. The author assumes no responsibility for any misuse.

For more real-world usage examples, see the examples/ directory.

Acknowledgments

  • STPyV8 — Design reference for the Python–V8 interop layer

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

iv8-0.1.3-cp314-cp314-win_amd64.whl (52.5 MB view details)

Uploaded CPython 3.14Windows x86-64

iv8-0.1.3-cp314-cp314-manylinux_2_28_x86_64.whl (77.7 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

iv8-0.1.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (83.9 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

iv8-0.1.3-cp313-cp313-win_amd64.whl (52.5 MB view details)

Uploaded CPython 3.13Windows x86-64

iv8-0.1.3-cp313-cp313-manylinux_2_28_x86_64.whl (77.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

iv8-0.1.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (83.9 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

iv8-0.1.3-cp312-cp312-win_amd64.whl (52.5 MB view details)

Uploaded CPython 3.12Windows x86-64

iv8-0.1.3-cp312-cp312-manylinux_2_28_x86_64.whl (77.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

iv8-0.1.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (83.9 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

iv8-0.1.3-cp311-cp311-win_amd64.whl (52.5 MB view details)

Uploaded CPython 3.11Windows x86-64

iv8-0.1.3-cp311-cp311-manylinux_2_28_x86_64.whl (77.8 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

iv8-0.1.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (83.8 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

iv8-0.1.3-cp310-cp310-win_amd64.whl (52.5 MB view details)

Uploaded CPython 3.10Windows x86-64

iv8-0.1.3-cp310-cp310-manylinux_2_28_x86_64.whl (77.8 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

iv8-0.1.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (83.8 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

iv8-0.1.3-cp39-cp39-win_amd64.whl (52.5 MB view details)

Uploaded CPython 3.9Windows x86-64

iv8-0.1.3-cp39-cp39-manylinux_2_28_x86_64.whl (77.7 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.28+ x86-64

iv8-0.1.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (83.8 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64

File details

Details for the file iv8-0.1.3-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: iv8-0.1.3-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 52.5 MB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for iv8-0.1.3-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 624f8971d6a306cf20803fe600279bb57e7e1492f7c80c88e28a5d4d7f21e3b6
MD5 287466a9ea30d0047af0f3cea9174025
BLAKE2b-256 c93e96df1f2510034670a1dd7ce2d9007e2d65631e1b77df934081dea3938db4

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp314-cp314-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.3-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a45ff0ec5e7aeae5fee28a3b3ed5b34251bccb452607a108d9f2c0f44375d83d
MD5 14eadbdd3c785ff506a70fbf3cff5b85
BLAKE2b-256 76980693e0636d48ab55d6cdb229d6544ee4692837dee1be4c62835166ac2af8

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 15432c1ca3f88b30cd9e53afd74462bee6314da5ec30ebaa5ef65062b72c7268
MD5 2357de50d3c3f93fb7d6660f3c2f6ec2
BLAKE2b-256 5a564df273b3d95cea0c1aca7f9ed6ad54a231a675ac46b98055829fee5434fa

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: iv8-0.1.3-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 52.5 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for iv8-0.1.3-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 dd6e2da0142c843497690d22a1e9b5778f7315e773a0f6bbff896a31deb953bc
MD5 b5116812242f5b0a983bef25bb0757d4
BLAKE2b-256 a81f47e46368034e7823c60816e78e842cee06d1968b1f0c1b40fcebe7e31b80

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.3-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 8460aac738dc42a13466a81706b5041e2a320d3b493fbe8a0899a18c083cbe8d
MD5 aaa3bc86d545b90393531ed8208da371
BLAKE2b-256 e7c1d24249eb09324be8f64c63bf258eacfd9ee1980c31f7fc0b91d226a7a573

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 a149cafff566062d40461a038fa7553a9e3155aedb69b6361e2c9c35db273a5b
MD5 18c2f24fd8a3d5e4c5c26b06af5264ab
BLAKE2b-256 83b38f1472d6561999ece49bceb3dbf943767715c57b2db25e2ce4de8f2da13e

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: iv8-0.1.3-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 52.5 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for iv8-0.1.3-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 977edb34d6558df39fdec1f18fafd2ccd5a9ec46ea0a8b0e73963d15c9a8853c
MD5 fe7eb5ab2b55cb7fefef476818403f72
BLAKE2b-256 2287a449f138de5925eb71195df9cfaed7675d4e23a15bc71b480ada7c092e22

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.3-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c6d6518ebb41e59cea276dadb845931a3f7a4860a4dbd4867f5e36a63891515d
MD5 0547e8e24220c876511841742b212c8a
BLAKE2b-256 3aca092c325a5309524b0520afa0a4a161a8f8d06a52f96db00d2abaf74eb641

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 f9abf7a87e47eac25a1334effc8b75a24b42a57c7cba6baea587dc5e85511a4d
MD5 69b8741d0211e42619040e99c8c094e5
BLAKE2b-256 b44ea47ebaab6bd243efcffd6fafdf4939724d923a8925fd68ae4636c9f2c049

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: iv8-0.1.3-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 52.5 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for iv8-0.1.3-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 c629f9542788ca9641b29e6587a42b6702f8f9955bdf9236fcf806f05705bf61
MD5 159becb4a99858fcc04d911f6cb9ea58
BLAKE2b-256 9677cad589e149167401cfd63bcaf35631a18daa0ee2fa5bc60312ae8ab975b1

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.3-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 60f0347b7dab1cf7ac9a299a8b15f702f3cbcac97dbc9b1702a94206c4da1989
MD5 7f951db6ef1183d03cba31c36d3422f5
BLAKE2b-256 565cfb6b698b9a8b98985c8094d3c0931f648e43faa9e3f96b51f373033ea803

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 d1ae2dc19883eaa8c42b5361c8a1dd8e9d80329187a66fbcc0c5de77958bdd7c
MD5 b6993c06a79556f57f2d81fddac3b76f
BLAKE2b-256 7dbed2f75e49cc58c393e1d15f5ca9558db0ca007c07b9761aed561638f2a447

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: iv8-0.1.3-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 52.5 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for iv8-0.1.3-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 663d9c76759c142f3328478185d4abc9b9b84a27f1f0e4a06a01903795fea725
MD5 231b234ed1c42b477bd3dabdc85c1089
BLAKE2b-256 fa9f4e81118f72167ca72ca81b6cdcd3374e555f5bede38fccfc44b83112d5bb

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.3-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 276357d01816f5c758b0cba81d98bbce84213410e2494a259a957a03bf1d5bd4
MD5 4875eb9ba6f0f4abf75bf64bdeb9d0d6
BLAKE2b-256 b9246814c910c2bc8be78380db97ead016695db9c64044373bb2f1606bf0a1fe

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 8c1a032754597a017f7b25cfd8cfec0fe9850b55abff9c6f3c84ad64f1dce25e
MD5 6f9c5d0d1e8e2796daefb7760fa0fe61
BLAKE2b-256 276ea9e9987022e05a76a8650f912465e00541a16eb0533f82303ef2a463dbb4

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: iv8-0.1.3-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 52.5 MB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for iv8-0.1.3-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 ae38979eb91af2c2353b4c845a315bfc945b2f8690404b62761b8cda3fe13e03
MD5 69e333c7b679b7e5ed14fdc95962eaf7
BLAKE2b-256 ea3020adaa73b7b77ed0ef4dc5c96ba3a3235b085dd59236ce456a866a40c039

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp39-cp39-manylinux_2_28_x86_64.whl.

File metadata

  • Download URL: iv8-0.1.3-cp39-cp39-manylinux_2_28_x86_64.whl
  • Upload date:
  • Size: 77.7 MB
  • Tags: CPython 3.9, manylinux: glibc 2.28+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for iv8-0.1.3-cp39-cp39-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 bb93b1286d5cb95243cff74be0b575e1e785e0e18bd49e922b1c5bb51dab460b
MD5 6bc1355cdc85636fa6ea3ada47f4b8f5
BLAKE2b-256 987eaa7802c5f42a8c29b22688869ec23c75a8b5d79ce41ab12524c678aef041

See more details on using hashes here.

File details

Details for the file iv8-0.1.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for iv8-0.1.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 69af3f3458986e21c603f2c174c39385cd03f49c3fdc97c81a0dd966adebe2c2
MD5 2a0d88002f9e4ee6ce1fd57428c87622
BLAKE2b-256 9fa534180d2c2bf0da6508497806e3e2e283fbdf1cf5649cb72ad906ccef7e9d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page