<p align="center">
  <img src="https://github.com/afterburner-sh/afterburner/raw/master/art/svg/afterburner-bg-2000x500.svg" alt="Afterburner" width="100%"/>
</p>

<p align="center">
  <strong>A polyglot, deterministic, sandboxed WebAssembly runtime. Run or compile Rust, Go, Python, JavaScript, TypeScript, Ruby, and C/C++ to one sealed, reproducible artifact, with memory limits, timeouts, and capability-gated I/O.</strong>
</p>

<p align="center">
  <a href="https://crates.io/crates/afterburner"><img src="https://img.shields.io/crates/v/afterburner?style=flat-square&color=e6832e" alt="crates.io"/></a>
  <a href="https://docs.rs/afterburner"><img src="https://img.shields.io/docsrs/afterburner?style=flat-square&color=2a9d8f" alt="docs.rs"/></a>
  <img src="https://img.shields.io/badge/rust-1.90%2B_(2024_ed)-blue?style=flat-square&logo=rust&logoColor=white" alt="MSRV"/>
  <img src="https://img.shields.io/badge/license-BUSL--1.1-orange?style=flat-square" alt="License"/>
  <a href="https://discord.gg/GfTJmZaNNn"><img src="https://img.shields.io/badge/discord-join%20chat-5865F2?style=flat-square&logo=discord&logoColor=white" alt="Discord"/></a>
</p>

---

Afterburner is a polyglot, deterministic WebAssembly runtime, and the way you build on it is by writing **packages**: small, sandboxed, capability-sealed units of Rust, Go, Python, JavaScript, TypeScript, Ruby, or C/C++ 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](#library-usage-embedding-the-engine) below.)

## Quickstart: build a package

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

```sh
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:

```javascript
// 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](#packages-registry--package-manager) for the full authoring reference.

## `burn`: the command-line runtime

### Install (prebuilt binaries)

Linux / macOS:

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

Windows (PowerShell):

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

Pin a specific version with `BURN_VERSION`:

```sh
# 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
# 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](https://github.com/afterburner-sh/afterburner/releases). 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)

```bash
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):

```bash
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/`](./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`](./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).

```sh
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](https://afterburner.sh/docs#packages).

---

## Use with AI coding agents

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

```sh
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:

```toml
[dependencies]
afterburner = "0.1"
```

```rust
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:

```rust
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](LICENSE)
(BSL 1.1). Each version released under the BSL automatically converts to the
[Apache License, Version 2.0](LICENSE-APACHE) **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`](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](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](LICENSING.md)**; contact
`info@afterburner.sh`.

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

---

<p align="center">
  <sub>BUSL-1.1 &rarr; Apache-2.0 (per-version, 4-year change)</sub>
</p>
