Skip to content

Runtime

JavaScript runtime.

Each Runtime runs on a dedicated OS thread with its own V8 isolate and provides async-first JavaScript execution with promise support.

Runtime objects are not thread-safe; all methods must be invoked from the thread that created the runtime while holding the Python GIL.

__init__

__init__(config: RuntimeConfig | None = None) -> None

Create a runtime instance with optional configuration.

Parameters:

Name Type Description Default
config RuntimeConfig | None

Optional :class:RuntimeConfig to customize heap limits, bootstrap scripts, inspector, etc.

None

eval

eval(code: str) -> Any

Evaluate JavaScript code synchronously.

This is a convenience method that blocks on the async evaluation. For better performance with promises, use eval_async() instead.

Parameters:

Name Type Description Default
code str

JavaScript source code to evaluate

required

Returns:

Type Description
Any

The native Python representation of the result (int, str, dict, list, etc.)

Raises:

Type Description
RuntimeError

If evaluation fails or times out

JavaScriptError

If JavaScript code throws an exception

Example
>>> runtime = Runtime()
>>> result = runtime.eval("1 + 1")
>>> print(result)
2

eval_async async

eval_async(code: str, *, timeout: float | int | timedelta | None = None) -> Any

Evaluate JavaScript code asynchronously.

This method supports promises and will wait for them to resolve. It's the recommended way to execute JavaScript code.

Parameters:

Name Type Description Default
code str

JavaScript source code to evaluate

required
timeout float | int | timedelta | None

Optional timeout (seconds as float/int, or datetime.timedelta)

None

Returns:

Type Description
Any

The native Python representation of the result (int, str, dict, list, etc.)

Raises:

Type Description
RuntimeError

If evaluation fails

JavaScriptError

If JavaScript code throws an exception

Example
>>> runtime = Runtime()
>>> result = await runtime.eval_async("Promise.resolve(42)")
>>> print(result)
42

register_op

register_op(name: str, handler: Callable[..., Any], *, mode: str = 'sync') -> int

Register a host operation that can be called from JavaScript.

Parameters:

Name Type Description Default
name str

Operation name (must be unique)

required
handler Callable[..., Any]

Python callable that handles the operation

required
mode str

Operation mode ("sync" or "async")

'sync'

Returns:

Type Description
int

Operation ID that can be used in JavaScript

Raises:

Type Description
RuntimeError

If registration fails

Note

Async handlers require an active asyncio context. Call :meth:Runtime.eval_async (or any other async entry point) at least once before invoking the op from JavaScript; otherwise the runtime will raise an error indicating that the event loop is not running.

Example
>>> def add_handler(a, b):
...     return a + b
>>> op_id = runtime.register_op("add", add_handler, mode="sync")
>>> # From JavaScript: __host_op_sync__(op_id, 10, 20)  # Returns 30

is_closed

is_closed() -> bool

Check if the runtime is closed.

Returns:

Type Description
bool

True if the runtime is closed, False otherwise

get_stats

get_stats() -> RuntimeStats

Capture a snapshot of runtime resource usage and execution counters.

Returns:

Name Type Description
RuntimeStats RuntimeStats

Structured metrics describing the runtime state.

inspector_endpoints

inspector_endpoints() -> InspectorEndpoints | None

Return the DevTools endpoints if the inspector is enabled.

Returns:

Name Type Description
InspectorEndpoints InspectorEndpoints | None

describing websocket and devtools:// URLs, or None when the runtime was created without inspector support.

close

close() -> None

Close the runtime and free all resources.

After calling close(), the runtime can no longer be used. This method is called automatically when using the runtime as a context manager.

terminate

terminate() -> None

Forcefully stop any running JavaScript and prevent future execution.

Must be invoked from the same thread that owns the runtime. After termination, subsequent operations raise RuntimeTerminated.

bind_function

bind_function(name: str, handler: Callable[..., Any]) -> None

Expose a Python handler as a global JavaScript function.

Parameters:

Name Type Description Default
name str

Global function name (assigned on globalThis)

required
handler Callable[..., Any]

Python callable invoked when JS calls the function

required
Note

If handler is async, the runtime must first establish asyncio context via :meth:Runtime.eval_async (or another async entry point). Calling an async-bound function from a purely synchronous evaluation without that context will result in an error about the event loop not running.

Example
>>> runtime = Runtime()
>>> def add(a, b): return a + b
>>> runtime.bind_function("add", add)
>>> runtime.eval("add(1, 2)")
3

stream_from_async_iterable

stream_from_async_iterable(iterable: AsyncIterable[Any]) -> PyStreamSource

Wrap a Python async iterable and expose it to JavaScript as a ReadableStream.

Parameters:

Name Type Description Default
iterable AsyncIterable[Any]

Object implementing __aiter__ that yields JSON-serializable chunks.

required

Returns:

Type Description
PyStreamSource

Handle that can be passed into JavaScript and consumed via stream readers.

bind_object

bind_object(name: str, obj: Mapping[str, Any]) -> None

Expose a Python mapping as a global JavaScript object.

Each key/value pair becomes a property on globalThis[name]. Values that are Python callables are bound as callable JavaScript functions, following the same async detection rules as :meth:bind_function.

Parameters:

Name Type Description Default
name str

Object name assigned on globalThis

required
obj Mapping[str, Any]

Mapping with string keys and JSON-serializable values or callables

required
Example
>>> runtime = Runtime()
>>> def add(a, b):
...     return a + b
>>> runtime.bind_object("api", {"add": add, "value": 42})
>>> runtime.eval("api.value")
42

set_module_resolver

set_module_resolver(resolver: Callable[[str, str], str | None]) -> None

Set a custom module resolver for JavaScript imports.

The resolver function is called whenever JavaScript code attempts to import a module. It receives the module specifier and referrer, and should return a fully-qualified URL or None to fall back to simple static resolution.

Parameters:

Name Type Description Default
resolver Callable[[str, str], str | None]

A callable that takes (specifier, referrer) and returns a fully-qualified URL string or None

required
Note

By default, no modules are loadable. You must either call this method, set_module_loader(), or add_static_module() to enable module loading.

Example
>>> def my_resolver(specifier, referrer):
...     if specifier == "my-lib":
...         return "static:my-lib"
...     return None
>>> runtime.set_module_resolver(my_resolver)

set_module_loader

set_module_loader(loader: Callable[[str], Any]) -> None

Set a custom module loader for JavaScript imports.

The loader function is called to fetch the source code for a module specifier. It should return the module source code as a string, or a coroutine that resolves to the source code for async loading.

Parameters:

Name Type Description Default
loader Callable[[str], Any]

A callable that takes a module specifier and returns the module source code as a string, or an awaitable that resolves to the source code

required
Note

By default, no modules are loadable. You must either call this method, set_module_resolver(), or add_static_module() to enable module loading.

Example
>>> def my_loader(specifier):
...     if specifier == "my-lib":
...         return 'export const value = 42;'
...     raise ValueError(f"Unknown module: {specifier}")
>>> runtime.set_module_loader(my_loader)

add_static_module

add_static_module(name: str, source: str) -> None

Add a static module that can be imported by JavaScript code.

This is syntactic sugar for pre-registering modules without custom resolvers. The module can be imported by its bare name (e.g., lib).

Parameters:

Name Type Description Default
name str

Module name (will be prefixed with static:)

required
source str

JavaScript source code for the module

required
Example
>>> runtime.add_static_module("lib", "export const value = 42;")
>>> result = runtime.eval_module("lib")
>>> print(result["value"])
42

eval_module

eval_module(specifier: str) -> Any

Evaluate a JavaScript module synchronously.

This is a convenience method that blocks on the async module evaluation. For better performance with async modules, use eval_module_async() instead.

Parameters:

Name Type Description Default
specifier str

Module specifier to evaluate

required

Returns:

Type Description
Any

The native Python representation of the module namespace (dict-like object)

Raises:

Type Description
RuntimeError

If module evaluation fails or times out

JavaScriptError

If JavaScript code throws an exception

Example
>>> runtime.add_static_module("lib", "export const value = 42;")
>>> result = runtime.eval_module("lib")
>>> print(result["value"])
42

eval_module_async async

eval_module_async(specifier: str, *, timeout: float | int | timedelta | None = None) -> Any

Evaluate a JavaScript module asynchronously.

This method supports async modules and will wait for them to resolve. It's the recommended way to evaluate modules.

Parameters:

Name Type Description Default
specifier str

Module specifier to evaluate

required
timeout float | int | timedelta | None

Optional timeout (seconds as float/int, or datetime.timedelta)

None

Returns:

Type Description
Any

The native Python representation of the module namespace (dict-like object)

Raises:

Type Description
RuntimeError

If module evaluation fails

JavaScriptError

If JavaScript code throws an exception

Example
>>> runtime.add_static_module("lib", "export const value = 42;")
>>> result = await runtime.eval_module_async("static:lib")
>>> print(result["value"])
42

__enter__

__enter__() -> Self

Context manager entry - returns self.

__exit__

__exit__(exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None) -> bool

Context manager exit - closes the runtime.