Quick Start
Installation
Create or activate a virtual environment inside your project and install the package:
Platform Support
Supports macOS (Apple Silicon) and Linux (x86_64, ARM64) with glibc (manylinux). Windows and musl-based distributions (e.g., Alpine) are not supported currently.
Start here: Pydeno
For code you did not write (an agent's, a user's), use Pydeno: a pool of pre-started workers, each
in its own OS sandbox and used for one session only. It has the same shape as Monty's Monty.
from pydeno import Pydeno
with Pydeno() as pool:
with pool.checkout() as session:
session.feed_run("const x = 20")
session.feed_run("x + 1") # 21
session.feed_run("await lookup(7)", external_lookup={"lookup": lambda i: i * 6}) # 42
from pydeno import AsyncPydeno
async with AsyncPydeno() as pool:
async with pool.checkout() as session:
await session.feed_run("1 + 1") # 2
The front-door guide covers the defaults, limits, errors, snapshots
and the Monty-to-pydeno mapping. The rest of this page is the in-process Runtime, for code you
trust.
Run JavaScript from Python
Use pydeno.eval to evaluate JavaScript code directly:
pydeno.eval() runs synchronously and returns the result immediately.
Run JavaScript from the command line
The pydeno command evaluates an expression in the sandboxed worker and prints the result as JSON:
It exits non-zero on a JavaScript error, with the error on stderr. See Command line
for --timeout, --max-memory, --raw and the exit codes.
Share functions and data
Bind Python callables or objects so they are visible from JavaScript:
import pydeno
pydeno.bind_function("notify", lambda msg: print("JS:", msg))
pydeno.eval("notify('hello from JS')")
pydeno.bind_object("config", {"debug": True})
pydeno.eval("config.debug")
Once bound, they will remain available to all subsequent evaluations.
Run code asynchronously
Use eval_async to run JavaScript without blocking Python’s event loop.
This is useful when JavaScript performs long-running work or returns a Promise.
import asyncio
async def main():
# JavaScript expression
result = await pydeno.eval_async("42")
# Code that returns a Promise is also supported
result = await pydeno.eval_async("Promise.resolve('done')")
print(result)
asyncio.run(main())
Keep types familiar
pydeno automatically converts common data types between Python and JavaScript, so you can work with familiar types on both sides. Numbers, strings, booleans, lists, dictionaries, and more are converted seamlessly.
# Python → JavaScript → Python
result = pydeno.eval("[1, 2, 3].map(x => x * 2)")
print(result) # [2, 4, 6]
For complete details on type conversion, including special types like undefined, BigInt, Date, and binary data, see Type Conversion.
Working with Runtime directly
pydeno vs. Runtime
The pydeno module provides a convenient interface that automatically manages a context-local Runtime for you.
Each asyncio task or thread gets its own isolated runtime instance, created lazily and cleaned up automatically.
This makes it perfect for everyday use where you just want to run JavaScript without managing runtime lifecycle.
For more control, you can work with the Runtime class directly:
from pydeno import Runtime
runtime = Runtime() # Create a runtime instance
runtime.eval("let counter = 0")
runtime.eval("counter++")
print(runtime.eval("counter")) # 1
runtime.close() # Clean up when done
Or use it as a context manager for automatic cleanup:
Each Runtime runs on a dedicated thread with its own V8 isolate, where state persists across evaluations.