afterburner 0.1.3

Afterburner - JS ~> WASM Sandboxed Execution VM
Documentation

Afterburner is a JavaScript runtime built in Rust, and the way you build on it is by writing packages: small, capability-sealed units of JavaScript or TypeScript that you scaffold, test, build into a single .afb file, and publish to a registry. It ships its own package format, registry, and Cargo-style package manager, so the whole workflow is one toolchain. (You can also embed the engine as a Rust library; see Library usage below.)

Quickstart: build a package

Install the toolchain, then scaffold, run, and publish a package:

curl -fsSL https://afterburner.sh | sh            # install the `burn` toolchain

burn init ./greeter --namespace nyquist --name greeter   # scaffold (add --ts for TypeScript)
cd greeter
burn run                                          # run the package entry (like `cargo run`)
burn test                                         # run tests/ in the sandbox
burn package                                      # build ./nyquist-greeter-0.1.0.afb
burn publish                                      # upload to the registry
burn clean                                        # remove build artifacts

A package is a directory with three parts: a manifest (afb.toml), a capability grant (manifold.json), and your source/. The entry exports one function that takes a JSON input and returns a JSON result:

// source/main.js
module.exports = function (input) {
  return { hello: (input && input.name) || "world" };
};

It is sealed by default: the scaffolded manifold.json grants nothing, so the code cannot touch the network, filesystem, or environment until you open a door. See Packages, registry & package manager for the full authoring reference.

burn: the command-line runtime

Install (prebuilt binaries)

Linux / macOS:

curl -fsSL https://afterburner.sh | sh

Windows (PowerShell):

iwr -useb https://afterburner.sh | iex

Pin a specific version with BURN_VERSION:

# POSIX (put the latest version if you want, below command might be outdated)
BURN_VERSION=v0.1.3 curl -fsSL https://afterburner.sh | sh
# PowerShell (put the latest version if you want, below command might be outdated)
$env:BURN_VERSION = 'v0.1.3'; iwr -useb https://afterburner.sh | iex

Or grab a tarball directly from the Releases page. Archives are named burn-<version>-<target>.tar.gz (or .zip for Windows) and ship with a .sha256 next to them.

Built with --features release-cli (every backend, every L3 shadow, TypeScript loader), so it's a single self-contained binary. No runtime libsqlite3, libssl, or libclang required. Plugin .wasm is include_bytes!-baked into the binary at build time.

Install (build from source)

cargo install afterburner --features bin   # installs the `burn` binary
burn ./script.js                           # run a file
burn -e 'module.exports = () => 42'        # eval inline
echo '{"n":21}' | burn thrust transform.js # UDF mode (stdin → JSON)
burn bench perf.js --iters 10000 --workers 8
burn repl                                  # interactive

Deno-style capability grants (deny by default):

burn --allow-net=api.example.com,*.trusted.io script.js
burn --allow-listen=8080 server.js         # inbound: port list or a lo-hi range
burn --allow-fs=/tmp,/var/data etl.js
burn --allow-env=HOME,PATH launcher.js
burn -A runall.js                          # grant everything

See examples/ for standalone projects covering single UDF, batched UDF, multi-worker scheduling, streaming crypto, HostContext + capability grants, and rebuilding burn in 30 lines. examples/express-app runs a real Express.js app: require('express') resolves the actual npm package out of node_modules/ and serves HTTP end-to-end.


Packages, registry & package manager

Afterburner ships its own package ecosystem: its own package format, its own registry, and a built-in package manager. You don't need npm to publish or consume Afterburner code (and npm packages can still be pulled in as dependencies when you want them).

  • .afb packages: a package is a single, content-addressed, compressed file: a manifest (afb.toml), a capability grant (manifold.json), and your source/. Sealed by default; what it may touch is declared and reviewable before anyone installs it. JavaScript or TypeScript (TS is transpiled to JS at pack time).
  • Registry: publish and install packages from the Afterburner registry (afterburner-cloud client + the afterburner-registry service). Coordinates are namespace/name@version; every release is pinned by SHA-256 digest.
  • Cargo-style package manager: burn install resolves the full dependency graph with a conflict-driven version solver, writes a reproducible burn.lock, and caches packages content-addressed. Two kinds of dependency, both declared (never vendored into your artifact): [dependencies] for other registry packages and [npm] for npm packages, which a native, pure-Rust installer fetches and integrity-checks (no install scripts, native/C-ABI addons rejected).
burn init ./greeter --namespace nyquist --name greeter   # scaffold (add --ts for TypeScript)
burn test                                             # run tests in the sandbox
burn add nyquist/json-tools                              # pin a registry dependency
burn install                                          # resolve + cache the graph → burn.lock
burn package                                          # build the .afb (deterministic)
burn publish                                          # upload to the registry

Full authoring guide and the dependency-security model are in the documentation.


Use with AI coding agents

One command routes every piece of JavaScript your AI assistant writes through the sealed sandbox instead of raw node:

burn agent install     # arrow-key multi-select: Claude Code, Codex, Gemini CLI, Cursor, Copilot, Antigravity
burn agent status      # what's detected, wired, and current
burn agent uninstall   # exact inverse - configs restored, nothing left behind

It wires a pre-tool hook into each assistant's config (plus a short instruction block where the assistant reads one). When the assistant tries node app.js, npm test, or npx tsx ..., the hook hands back the corrected command - burn --sandbox node app.js - and the assistant re-runs it sealed: no network, no filesystem, no env access. Capabilities are granted per run, narrowly, only when the code genuinely needs them (burn --sandbox --allow-net=api.example.com node app.js). Runtime failures surface in the conversation prefixed BURN: so they're unmistakably the runtime speaking. One-off bypass: BURN_AGENT_HOOK=0.


Library usage (embedding the engine)

Besides the package toolchain, you can embed the engine directly in a Rust program to run untrusted JavaScript inside your own application. Add the crate, register a script, hand it JSON, get JSON back:

[dependencies]
afterburner = "0.1"
use afterburner::Afterburner;
use serde_json::json;

let ab = Afterburner::new()?;
let id = ab.register("module.exports = (d) => d.n + 1")?;
let out = ab.run(&id, &json!({ "n": 41 }))?;
assert_eq!(out, json!(42));

The default picks the best mode available (adaptive: native on the first call, WASM-sandboxed thereafter). Use Afterburner::builder() for mode, limits, and capabilities:

use afterburner::{Afterburner, Manifold, FsAccess};

let ab = Afterburner::builder()
    .fuel(1_000_000_000)
    .memory_bytes(64 << 20)
    .timeout_ms(30_000)
    .manifold(Manifold {
        fs: FsAccess::ReadWrite(vec!["/var/data".into()]),
        ..Manifold::sealed()
    })
    .threaded(8)
    .build()?;

Workspace Crates

Crate Purpose
afterburner Facade: Afterburner + builder, burn binary, one ergonomic entry point
afterburner-core Combustor trait, Manifold, FuelGauge, BurnCache, level-gated logging
afterburner-ignite Native JS engine, thread-local runtimes
afterburner-wasi Wasmtime sandbox with host-function imports, pooling allocator + InstancePre, bytecode cache
afterburner-node-compat plenum.js polyfill bundle + Rust-backed host impls (incl. bounded HTTP + DNS with per-call timeouts)
afterburner-flow High-level FlowEngine::load/execute/unload for flow-style pipelines
afterburner-adaptive Flying Start: native → WASM tier switch
afterburner-thrust Multi-threaded scheduler: bounded per-worker queues + global injector, token-bucket admission, NUMA-aware steal-when-idle, graceful drain
afterburner-plugin WASM-side runtime plugin (wasm32-wasip1)

License

Afterburner is source-available under the Business Source License 1.1 (BSL 1.1). Each version released under the BSL automatically converts to the Apache License, Version 2.0 four years after that version's release (its per-version Change Date). Versions released before the relicense (git tag last-apache-2.0) were never under the BSL and remain Apache-2.0.

The Apache-2.0 components shipped alongside the engine (everything under examples/ (see examples/LICENSE), plus the planned afterburner-afb and burn/* packages) are Apache-2.0 via their own LICENSE / license metadata and not subject to the BSL.

Free for non-commercial and non-production use. Individuals on personal projects, students on coursework, and non-commercial open-source projects (no paid sponsorship, no monetised hosting, no enterprise SLA), plus any internal evaluation/development/testing, are explicitly welcome, no separate agreement needed (see the Additional Use Grant in LICENSE).

Commercial license required to host, embed, or compete. Offering Afterburner as a hosted/managed service, embedding it in a commercial product distributed to third parties (OEM), or using it to build a competing offering requires a commercial license, including via forks, rebrands, vendored, or embedded copies. See LICENSING.md; contact info@afterburner.sh.

"Afterburner" and related marks are trademarks of vertexclique; see TRADEMARK.md. Contributions require a CLA.