LILYLILYDOCS
Docs/CLI/run

lly run

Run a .brick bundle through the local runtime plugin.

lly run executes a brick on your machine using the same Wasmtime-based runtime that the CAP fleet uses in production. The contract is deliberate: if a brick runs locally, it almost always runs on the fleet. The local runtime, the sandbox boundary, the WASI surface, and the multi-brick linker are bit-for-bit identical to what lly void deploy ships.

Synopsis

lly run [OPTIONS] <BRICK> [-- <args>]

The single positional argument is the path to a .brick file produced by lly compile, lly nextjs, or any other frontend plugin. Everything after the -- separator is forwarded verbatim to the guest as argv.

Example

run
$ lly compile hello.c -o hello.brick → frontend-c v0.8.2 · 1 TU · 18 LOC ✓ wrote hello.brick (34 KB) $ lly run hello.brick -- world hello, world ✓ exit 0 · 14ms

Passing arguments

Use a literal -- to separate flags meant for lly from flags meant for the guest. The runtime exposes the tail as argv with argv[0] set to the brick's manifest name. Bricks compiled from C and C++ read these through main(int argc, char **argv). JavaScript bricks read them via process.argv.

argv
$ lly run wc.brick -- --lines README.md 142 README.md ✓ exit 0 · 9ms

Environment

By default no host environment is leaked into the guest. Pass variables explicitly with --env KEY=VAL, repeated as needed. Use --env-host to inherit the full host environment when you really mean to. Both flags compose: explicit --env entries override inherited ones.

env
$ lly run server.brick --env PORT=8080 --env LOG=debug listening on :8080

Stdio

Guest stdout and stderr are wired directly to the host terminal. The guest's stdin is inherited from the parent process, so pipelines work the way you would expect.

pipe
$ cat input.txt | lly run upper.brick > out.txt ✓ exit 0 · 22ms

Timeout

Use --timeout <SECONDS> to cap wall-clock execution. The runtime injects an epoch interruption and tears the guest down cleanly; the guest sees a trap, the host returns a non-zero exit code. The default is no timeout. Production CAPs apply their own per-request budgets independent of this flag.

Multi-brick mode

Bricks can be single-module or multi-module. Multi-brick bundles link several WASM modules sharing one linear memory and are opt-in at compile time. To execute them, pass --multi so the runtime loads the full linker plan instead of a single-module fast path. If you forget the flag on a multi-brick bundle, lly run prints a clear diagnostic pointing at the manifest. The same flag is implicit when the fleet runs the brick, so you only ever care about it locally.

multi
$ lly run app.brick --multi -- --serve → runtime v0.14.1 · 4 modules · shared memory 16 MiB listening on :3000

Working directory and files

The runtime mounts the current working directory as the guest's root WASI preopen. Relative paths inside the brick resolve against the directory you launched lly run from. Use --cwd <PATH> to point somewhere else, or --no-fs to deny filesystem access entirely.

Exit codes

lly run propagates the guest exit code. A WASI I32Exit(n) surfaces as exit n. A trap (unreachable, out-of-bounds, division by zero) surfaces as exit 134 with a stderr diagnostic and a symbolicated stack frame when debug info is present in the brick.

See also

lly compile produces the bricks you run. lly bundle inspect shows what is inside one before you execute it. The brick format documents the underlying bundle layout. lly doctor verifies that the runtime plugin is installed and healthy.