Skip to main content

Sandboxed JavaScript execution for Python, via PyO3 + rquickjs.

Project description

quickjs-rs

Sandboxed JavaScript execution for Python.

Native Python extension (PyO3 + rquickjs) wrapping quickjs-ng (a QuickJS fork). Single self-contained wheel, zero runtime dependencies, microsecond-range runtime startup. ES modules with a composable scope registry. Inline TypeScript support via oxidase.

[!WARNING] quickjs-rs is experimental. Before putting this in production, you should read the Security guide.

Install

pip install quickjs-rs
uv add quickjs-rs

Wheels ship for Linux (x86_64 + aarch64), macOS (x86_64 + arm64), and Windows (x86_64), against Python 3.11, 3.12, and 3.13.

Quickstart

from quickjs_rs import Runtime

with Runtime() as rt:
    with rt.new_context() as ctx:
        assert ctx.eval("1 + 2") == 3

        # Register a Python callable as a JS global.
        @ctx.function
        def greet(name: str) -> str:
            return f"hi {name}"
        assert ctx.eval("greet('world')") == "hi world"

Async + top-level await:

import asyncio

async def main():
    with Runtime() as rt:
        with rt.new_context() as ctx:
            @ctx.function
            async def fetch_thing() -> str:
                await asyncio.sleep(0.01)
                return "from python"

            result = await ctx.eval_async("await fetch_thing()")
            assert result == "from python"

asyncio.run(main())

ES modules

Register modules via ModuleScope, then import them from module-mode eval. Scopes are recursive, self-contained resolver boundaries — each scope sees only what its own dict declares.

from quickjs_rs import ModuleScope, Runtime

stdlib = ModuleScope({
    "@agent/utils": ModuleScope({
        "index.js": """
            export { slugify } from './strings.js';
        """,
        "strings.js": """
            export function slugify(s) {
                return s.toLowerCase().replace(/ /g, '-');
            }
        """,
    }),
    "@agent/config": ModuleScope({
        "index.js": "export const MAX_RETRIES = 3;",
    }),
})

with Runtime() as rt:
    with rt.new_context() as ctx:
        rt.install(stdlib)
        assert await ctx.eval_async("""
            const { slugify } = await import("@agent/utils");
            const { MAX_RETRIES } = await import("@agent/config");
            slugify("Hello World") + '/' + MAX_RETRIES;
        """) == "hello-world/3"

Shared deps are declared by spreading (**utils.modules) into each scope that needs them. Resolver conventions are documented in AGENTS.md.

TypeScript

Source strings whose key ends in .ts, .mts, .cts, or .tsx are type-stripped at install() time via oxidase. Enums, namespaces, and parameter properties are transformed; plain type annotations erase to whitespace. No type checking — run tsc --noEmit separately if you want that.

rt.install(ModuleScope({
    "@util": ModuleScope({
        "index.ts": """
            export enum Mode { Strict = 1, Loose = 2 }
            export function slug(s: string, mode: Mode): string {
                return s.toLowerCase().replace(/ /g, mode === Mode.Strict ? '_' : '-');
            }
        """,
    }),
}))

TypeScript syntax errors surface at install() time (oxidase parses during stripping) rather than at eval.

Snapshots

quickjs-rs can snapshot the restorable portion of a context's script-mode top-level state and restore it into another context.

It does not attempt to snapshot module-local bindings, pending async work, host callback identity, or full lexical-environment state.

from quickjs_rs import Runtime, Snapshot

with Runtime() as rt:
    with rt.new_context() as ctx:
        ctx.eval("""
            const shared = { count: 1 };
            const a = shared;
            const b = shared;
        """)
        snap = ctx.create_snapshot()
        payload = snap.to_bytes()

with Runtime() as rt2:
    with rt2.new_context() as ctx2:
        snap = Snapshot.from_bytes(payload)
        rt2.restore_snapshot(snap, ctx2)
        assert ctx2.eval("a === b") is True
        assert ctx2.eval("a.count") == 1

Snapshot creation supports two policy knobs:

  • on_missing_name: skip, tombstone, or error
  • on_unserializable: tombstone or error

Example:

with Runtime() as rt:
    with rt.new_context() as ctx:
        ctx.eval("const fn = () => 1;")
        snap = ctx.create_snapshot(on_unserializable="tombstone")

On restore, a tombstoned name is installed as a global property whose getter throws a descriptive error if read. This makes missing or unserializable bindings explicit instead of silently disappearing unless you choose skip.

Async contexts use the same snapshot model:

snap = await ctx.create_snapshot_async(on_missing_name="tombstone")
rt.restore_snapshot(snap, other_ctx, inject_globals=True)

Security

  • This library is not a host-memory isolation boundary. The JS engine (quickjs-ng via rquickjs/rquickjs-sys) runs in the same process/address space as Python.

    • When running untrusted or semi-trusted JS, run execution in isolated worker processes/containers with restricted network/filesystem access and recycle workers on timeout/OOM/failure.
  • Registered host callbacks are capability boundaries. Any callback exposed to JS should be treated as privileged if this runtime is being used to run untrusted code

  • Do not share a single Runtime across different trust domains/tenants. Use one runtime per trust domain to avoid cross-context module contamination.

See .github/THREAT_MODEL.md for more information on the threat boundaries and supply-chain posture of quickjs-rs

Development

# Dev install (maturin handles the Rust build).
pip install -e ".[dev]"
maturin develop --release

# Run tests, type-check, lint.
pytest
mypy quickjs_rs
ruff check

License

MIT. See LICENSE.

Project details


Download files

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

Source Distribution

quickjs_rs-0.1.1.tar.gz (155.1 kB view details)

Uploaded Source

Built Distributions

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

quickjs_rs-0.1.1-cp313-cp313-win_amd64.whl (1.3 MB view details)

Uploaded CPython 3.13Windows x86-64

quickjs_rs-0.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

quickjs_rs-0.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.3 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

quickjs_rs-0.1.1-cp313-cp313-macosx_11_0_arm64.whl (1.3 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

quickjs_rs-0.1.1-cp313-cp313-macosx_10_12_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

quickjs_rs-0.1.1-cp312-cp312-win_amd64.whl (1.3 MB view details)

Uploaded CPython 3.12Windows x86-64

quickjs_rs-0.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

quickjs_rs-0.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

quickjs_rs-0.1.1-cp312-cp312-macosx_11_0_arm64.whl (1.3 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

quickjs_rs-0.1.1-cp312-cp312-macosx_10_12_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

quickjs_rs-0.1.1-cp311-cp311-win_amd64.whl (1.3 MB view details)

Uploaded CPython 3.11Windows x86-64

quickjs_rs-0.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

quickjs_rs-0.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.3 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

quickjs_rs-0.1.1-cp311-cp311-macosx_11_0_arm64.whl (1.3 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

quickjs_rs-0.1.1-cp311-cp311-macosx_10_12_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

File details

Details for the file quickjs_rs-0.1.1.tar.gz.

File metadata

  • Download URL: quickjs_rs-0.1.1.tar.gz
  • Upload date:
  • Size: 155.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for quickjs_rs-0.1.1.tar.gz
Algorithm Hash digest
SHA256 dca00dd71d20e5e1077a17b78b82ba77971b85d6b887a9ce2050cf0f170d6181
MD5 bc4ed28428a97350fdba8aefe078329c
BLAKE2b-256 440721e43cc4eb225735c49123d913880e95d1dcdae53bb2c919fe7ae411a75c

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1.tar.gz:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickjs_rs-0.1.1-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: quickjs_rs-0.1.1-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for quickjs_rs-0.1.1-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 921ab8f582a681ace7aadc4804274a355e8ade6726f3042c8603ae65f096f8b6
MD5 97904bf0da0b118beeb8765fe29f1689
BLAKE2b-256 b3740514092306a8724988c7c801d76c780cab9893b50fa754856b48351dac3e

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1-cp313-cp313-win_amd64.whl:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickjs_rs-0.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for quickjs_rs-0.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ca19331c8e3262f4b12e2031147790a2a9b531168aa6736fe02aff2739ca6ec3
MD5 183536a7b57aa2fa1c462d3b27ccbe59
BLAKE2b-256 394c004c43f2dd0aa20cc68121ed62aa7f51a0e1d05bca77f3e19d21896ba4c1

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickjs_rs-0.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for quickjs_rs-0.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 9d74092e86f32e2fbc01ca3c59609e6a2c890dbe5520f55f40fd1a6a7b3644cc
MD5 735ced0db205b67185d5f520e3a649e1
BLAKE2b-256 1ba18b9dcde82310bdee15ce739daf8c694e9614481d784782a70c115cb666cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickjs_rs-0.1.1-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for quickjs_rs-0.1.1-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 adaaff07c0c7e2a4cbcdb0c08d2bb1c3dd49cee7f0420b876708c50f33774366
MD5 746ba155c9c6d4f11b9bac604450c927
BLAKE2b-256 7c6173f1c94073714d6bc595ea3fcc7a5c5d92e775a5dc7ee87db45d9891d447

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickjs_rs-0.1.1-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for quickjs_rs-0.1.1-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 807f28ec12f5d0fc2c3c6909f0e6413a19354f066ad681e6d6c27f1202d10ee4
MD5 5fb4ee639ddb12809e9c3f93c372e065
BLAKE2b-256 70d19ac9ee9ab588256275ba41c8108f5e15e1f82b82fecf81b94665036f6d5f

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1-cp313-cp313-macosx_10_12_x86_64.whl:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickjs_rs-0.1.1-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: quickjs_rs-0.1.1-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for quickjs_rs-0.1.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 0eda9e042897a89b33e93a5d33108748f420ade3f1f272d3ac559691447ff2b0
MD5 e163758c023a5b2cbe0584b46a4d519a
BLAKE2b-256 87c076b418b43c17311477ada92d8202d87f0c9356ab7fca3fb9ee5054355e68

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1-cp312-cp312-win_amd64.whl:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickjs_rs-0.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for quickjs_rs-0.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d212da4dd173777fd0b50fa959b19290411ee6e42bfa0d23402501a4f7210d97
MD5 17a388aab83460808803f9864b55a8f7
BLAKE2b-256 8d5c2ec910fbc2fa39809b023f114543b50db7c6dbe3402a6f71e280518fb10e

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickjs_rs-0.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for quickjs_rs-0.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 dc4fedb2fd8df5b0463c16f87d1638157a98602fffc6532d2e19c580f2dd729d
MD5 bd1c1eee526349b8e856638c989b40b1
BLAKE2b-256 c88bb584840b331479c3be4b2c14a8227a7217ba711119d175692d8c46c15a41

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickjs_rs-0.1.1-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for quickjs_rs-0.1.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8a0ec9828ff774f6ef7d94723cd825e56ef1a7e9b409737d83cb7fcd00781fe8
MD5 413471e58edfbc0a7831f465b3f00e21
BLAKE2b-256 19f0b9e8260e072ab25749a3d59ef432af57a76c44353287acd0faa4227c96e1

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickjs_rs-0.1.1-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for quickjs_rs-0.1.1-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 e64320e37e3b4383fcee9566c223cc06702e6a94855daa6f47de3123513acb16
MD5 ccf7b6c901ed7de4b2acef3ee7c33dd1
BLAKE2b-256 ad294bcf9a3998f1d5f4e4a28b14f0b1045a99fb504a5eb73247c797b74da8db

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1-cp312-cp312-macosx_10_12_x86_64.whl:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickjs_rs-0.1.1-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: quickjs_rs-0.1.1-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for quickjs_rs-0.1.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 3016646589e470d5ae4412c07d49fba661bc72b15ee4f16bbcfa06b36356746d
MD5 cf9cde15108683ef0ece33fc271c70a2
BLAKE2b-256 745e09a5d609d4d0d35f4c6ba172a174008e67f078f41098a752cc66a39cd5f6

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1-cp311-cp311-win_amd64.whl:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickjs_rs-0.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for quickjs_rs-0.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b5f1d7a198b9869477ba3036f4495fb3369ad6f34694dc5175aa393f216d9f42
MD5 b155831444b3a6b326ebfde8bce12841
BLAKE2b-256 0fb826752067eebcde20e7fa17f6cdac91677410500c337c2074e48d5e54b48f

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickjs_rs-0.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for quickjs_rs-0.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 8e1cf58a848577439ed896ef78c3840784368f8846856d7412fe2e0fab8b5b24
MD5 336e135a65663460f860718abdfa7991
BLAKE2b-256 25a2f885fc8864e5df27ae7610963adab34925ba7e4dd093300c8493cba88353

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickjs_rs-0.1.1-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for quickjs_rs-0.1.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1a6044dbbec3f3fc037f17a354417f798f8c6e9610723f33a3b6b2e47b38ef6b
MD5 96349f36cd1696a7d4b2ff4d148f8842
BLAKE2b-256 945c6672f3c9aa37d220a1480713e96d6cbb89843fce1a06ee50da4e27d8ecb1

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickjs_rs-0.1.1-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for quickjs_rs-0.1.1-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 91c420a95d0b6d49ba699c8c8333eade3d50aa06d919bed334f06304a0600a04
MD5 871935d091b68492348792dd9afde998
BLAKE2b-256 bce9ff1cd72aa259ba61a36dc77a4440099ce1affb8a3eb7fd32f90a3b850668

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickjs_rs-0.1.1-cp311-cp311-macosx_10_12_x86_64.whl:

Publisher: release.yml on langchain-ai/quickjs-rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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