Install
Get a compiler on your machine
There is nothing to install if you only want to read and run — the workbench and terminal are the same compiler as a 7.3 MB wasm module. Install when you want native speed, OpenMP, or to link Viv output into something else.
Build from source
Rust is the only prerequisite. Viv is a cargo workspace member, so one command builds it:
git clone https://github.com/AdamZettel/viv
cd viv
cargo build --release -p viv
The binary lands at target/release/viv. Put it on your PATH or call
it where it is. cargo install --path lang/viv works too if you would rather it go
to ~/.cargo/bin.
The workspace pins blake3 to the 1.5 line, because newer releases pull a
dependency that needs Rust edition 2024. Anything from Rust 1.77 up will build it.
Check that it works
The test suite covers the kit and all four languages built on it:
cargo test --workspace A first program
A restricted Hartree–Fock calculation on H₂ in an STO-3G basis (the Gaussian integrals, the Fock build and the self-consistent-field loop, all in Viv), compiled to C and run:
$ viv lang/viv/examples/h2_sto3g.viv -o h2.c
wrote h2.c (624 IR nodes, 1891 debug entries)
$ wc -l h2.c
4637 h2.c
$ cc -std=c99 -O2 h2.c -lm -o h2 && ./h2
...
narrate: Converged.
narrate: Final E_total (hartree):
E_total: -1.11671
PASS H2/STO-3G total energy near textbook -1.117
That -1.11671 is the Szabo & Ostlund reference value, and the
PASS line is the program checking itself — the test block is in the
source, and what it prints is the claim the author wrote. The C needs no library but
libm.
With OpenMP
parallel for becomes an OpenMP pragma, so the compiled program needs the runtime
flag to use it. On macOS with Homebrew's libomp:
cc -std=c99 -O3 -Xpreprocessor -fopenmp \
-I/opt/homebrew/opt/libomp/include -L/opt/homebrew/opt/libomp/lib \
program.c -lomp -lm -o program
OMP_NUM_THREADS=8 ./program On Linux with gcc, add -fopenmp.
What compiling is for
The interpreter answers quickly and is the one the browser runs. For long runs, compile the same source to C: the compiled program's speed comes from the C compiler's optimizer (clang or gcc), since Viv itself contains no optimizer.
Compile straight to wasm
The direct backend skips C and emits a module itself. So far it handles numbers, arrays, control flow and functions (see the backend matrix), and on anything else it stops with an error naming the unsupported feature:
$ viv sumsq.viv -o sumsq.wasm
wrote sumsq.wasm (317 bytes wasm) The module imports the transcendentals and an output hook from its host, so running it takes a few lines of JavaScript and no runtime. The internals page pulls one of these apart section by section.
Build the browser compiler
The wasm module this site runs on is built from the same crate, as a cdylib against
wasm32-unknown-unknown without emscripten or wasm-bindgen.
JavaScript calls its exported functions directly, passing bytes through a shared buffer:
cd www
sh ./build-wasm.sh # -> www/public/viv/viv.wasm
npm install && npm run dev
The script passes --remap-path-prefix so no local filesystem path ends up in the
served binary (rustc embeds source paths in panic messages), and then greps the output to
check. The site build needs neither Rust nor this script; it serves the viv.wasm the
script produced.
Editor support
None yet, beyond the Monaco grammar the workbench registers. An LSP
server is the likely next step, and most of what it needs exists: every IR node already carries
a span, and diagnostics are structured values with a JSON renderer. Until then,
viv file.viv -o /dev/null type-checks a file and prints its diagnostics.
Prebuilt binaries
Not published yet. The plan is macOS arm64 first and linux x86_64 next, attached to a GitHub release with checksums, once the small open items in the project's list of gaps are fixed. The project publishes no binaries until then.