Open-source project
a16z/jolt avatar
a16z/jolt

Jolt, the RISC-V zkVM built around a single lookup table

The simplest and most extensible zkVM. Fast and fully open source from a16z crypto and friends. ⚡

1,056 stars345 forksRustApache-2.0

At a glance

What is it?
Jolt is a16z's Rust zkVM that proves RV64IMAC guest programs through lookup arguments, with a source-only install path, a tracing and heap profiling story, and a tracer that cannot attach a debugger. It is usable for experimentation today and explicitly not production ready.
Who is it for?
Engineers prototyping zero-knowledge proofs in Rust can use Jolt now to get a real prover running on an RV64IMAC guest, and the pinned toolchain plus the quickstart guide in the Jolt Book are enough to do it. Teams that need audited code, a stable public interface, or any production guarantee should look elsewhere, because the project states Jolt is in alpha and is not suitable for production use at this time.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One lookup table for the whole guest program

Jolt is a zkVM written in Rust: a virtual machine that executes a guest program and produces a zero-knowledge proof that the program ran correctly. The audience is engineers who need to prove a claim about off-chain computation, and the target instruction set is RV64IMAC. The design decision worth understanding is what happens to arithmetic. Rather than expanding every multiplication and bit operation into constraints that a sumcheck has to grind through, Jolt routes instruction semantics through lookup tables. That is why the package description in Cargo.toml reads "The lookup singularity. Based on Spartan; built on Arkworks", and why the paper behind it is titled "Jolt: SNARKs for Virtual Machines via Lookups".

The rest of the lineage is named in the README too: Lasso, for the lookup argument itself, and Twist and Shout, for memory checking via one-hot addressing and increments. A team evaluating a zkVM should still ask three concrete questions. What can the guest actually execute, how heavy is the build, and how far is the implementation from something you would trust with money. The answers here are narrower, heavier, and further away than the marketing phrasing suggests.

RV64IMAC is the boundary, and riscv-arch-test is the harness

The repository implements Jolt for the RISC-V 64-bit Base Integer Instruction Set, the M extension for integer multiplication and division, the A extension for atomic operations, and the C extension for compressed instructions. That list is the real execution boundary. It excludes 32-bit guests and floating point, and it includes atomics and compressed encodings. A guest is Rust code compiled to RV64IMAC, never arbitrary native code, and every claim you want to prove has to fit inside that instruction set.

Conformance to the ISA is treated as a first-class concern. The Makefile exposes targets named arch-tests-64imac, arch-tests-generate, arch-tests-run and arch-tests-smoke, wired to a riscv-arch-test submodule under third-party/, a configuration file at tests/arch-tests/jolt/test_config.yaml, a skip list at tests/arch-tests/skip.txt and a runner script at tests/arch-tests/run.sh. The emulator the runner drives is the debug build of jolt-emu from the tracer crate:

bash
cargo build -p tracer --bin jolt-emu

The Makefile notes that the debug build is deliberate, because arch tests are correctness-sensitive and do not benefit from release optimisation. The presence of a skip list also tells you the suite is not run green on every instruction, though the README does not say which cases are excluded.

Building from source with a pinned toolchain

There is no binary distribution here. The installation path is source only, and the toolchain version is pinned by a file named rust-toolchain.toml at the repository root. If you have rustup, the pinned toolchain and any additional targets install themselves on the first cargo invocation, so the whole setup is a clone, a check, and an install:

bash
git clone [email protected]:a16z/jolt.git
cd jolt; rustup show
cargo install --path .

The rustup show call is the verification step. It confirms that rustup selected the version the project pinned rather than whatever is on your default toolchain, which is the kind of detail that otherwise surfaces as a confusing compiler error an hour into a build.

The repository is a Cargo workspace, and the README notes that each workspace can be built individually. The prover package is jolt-prover, and a separate build-fast profile exists for quicker incremental builds:

bash
cargo build -p jolt-prover
cargo build --profile build-fast -p jolt-prover

Tests and examples follow the same pattern. The prover test suite runs under nextest with the prover-fixtures feature enabled, and examples in the examples directory are run as packages, for instance:

bash
cargo nextest run -p jolt-prover --features prover-fixtures
cargo run --release -p sha2-chain

The examples directory lists programmes covering fibonacci, sha2-chain, sha3-chain, btreemap, collatz, merkle-tree, field-ops, recursion, multi-function and signature verification for p256 and secp256k1, which tells you the intended workload profile: hashing, tree structures and elliptic curve checks rather than general compute.

Profiling produces trace.json, summary.json and memory.html

Because a prover is expensive, the repository puts observability in the open. Jolt is instrumented with the tokio-rs/tracing crate, and the tracing output can be written as a Chrome trace. Profiling is behind a cargo feature, so the cost is opt-in:

bash
cargo run --release -p jolt-prover --features profiling -- profile --name fibonacci --format chrome

The name argument is restricted to a known set: fibonacci, sha2-chain, sha3-chain or btreemap, matching guest programmes in the examples directory. The command writes a timestamped directory under benchmark-runs containing trace.json, summary.json and memory.html. The trace opens directly in Perfetto, and CPU and memory counters are included, which matters because the interesting question for a lookup-based prover is where the sumcheck work actually concentrates.

Memory has a separate path. Jolt uses the allocative crate and records per-batch heap snapshots for its live sumcheck state, enabled with a second feature:

bash
cargo run --release -p jolt-prover --features profiling,allocative -- profile --name fibonacci --format chrome

Heap totals land in summary.json and are rendered into memory.html. For scaling questions there is a sweep mode, driven by minimum and maximum scale values:

bash
cargo run --release -p jolt-prover --features profiling -- benchmark --min-scale 18 --max-scale 21 --resume

The resume flag suggests interrupted sweeps are expected, which is a good sign for jobs that run long. The project also states that benchmarking runs during CI to track prover runtime and peak memory over time.

The tracer cannot attach a debugger, so backtraces carry the debugging load

This is the sharpest limitation in the repository. The README states plainly that Tracer, Jolt's emulator, does not currently support attaching a debugger. It does support backtraces for panics inside guest programmes, but symbols are stripped from release guest ELF files by default, so a backtrace without help is close to useless. Debug and dev builds preserve symbols automatically.

There are two ways to get resolution back. The ad-hoc route is an environment variable. JOLT_BACKTRACE=1 keeps the call stack captured and enables symbol resolution, while the full variant adds register snapshots and cycle counts per frame:

bash
JOLT_BACKTRACE=1 cargo run --release -p example
JOLT_BACKTRACE=full cargo run --release -p example

The baked-in route puts the setting in the attribute on the function itself, which also forces frame pointers into the build for external unwinding tools:

rust
#[jolt::provable(backtrace = "dwarf")]
fn my_function(input: u64) -> u64 { ... }

Valid values are "off", "dwarf" and "frame-pointers", and the same effect can be requested from the command line through jolt build --backtrace enable. Two more conveniences round this out. print! and println! work in guest programmes, with no_std guests importing them via use jolt::println, and the README recommends running the corresponding trace_analyze for a given provable function during debugging, which skips instantiating the prover entirely and shortens the iteration loop. For anyone used to stepping through a guest, that substitution is the main adjustment.

Alpha releases, two licence files, and a version string that trails the tags

Every tagged release carries an alpha suffix. The list runs v0.2.1-alpha on 2025-08-29, v0.2.2-alpha and v0.3.0-alpha both on 2025-10-01, the latter noted for RV64 support. The repository is not archived and the last push was on 2026-10-15, so the tree is moving, but the versioning tells you what kind of movement: a sequence of alpha tags rather than a stable line you can pin to. The README is explicit that Jolt is in alpha and is not suitable for production use at this time.

There is a mismatch worth noticing if you are picking a dependency version. The root Cargo.toml still declares version = "0.1.0", while the released tags are in the v0.2 and v0.3 range. Anyone reading the manifest rather than the tag list will get a different idea of the crate's maturity than the release page suggests.

Licensing is Apache-2.0 according to the repository metadata, and the project describes itself as fully open source. The top level carries both LICENSE-APACHE and LICENSE-MIT, and Cargo.toml points license-file at a file named LICENSE, so the tree contains both a dual-licence arrangement and a single-licence pointer at once. The README does not explain the arrangement, so if the choice between Apache-2.0 and MIT matters for how you redistribute a derivative, that is a question to settle with the maintainers rather than infer from file names.

Two prover paths in one workspace, and three papers to read first

The Cargo workspace member list is where the architecture shows itself. Alongside the main crates, there is a family of narrowly named pieces: jolt-claims, jolt-claims-derive, jolt-program, jolt-witness and jolt-witness-derive, jolt-poly, jolt-sumcheck, jolt-openings, jolt-lookup-tables, jolt-transcript, jolt-field, jolt-hyperkzg and jolt-dory. Splitting the macros from the crates they generate is a deliberate move, because the guest side is transformed by derive code rather than called as a library. The package list also shows jolt-riscv, jolt-tracer-x86, jolt-metal and jolt-kernels, so the same prover is expected to run on more than one host architecture.

More interesting is the pair of prover paths. The workspace contains crates/jolt-spartan-prover and crates/jolt-spartan-verifier next to crates/jolt-lean-gen, and the author list credits the original Spartan paper author and the contributors to the Arkworks Spartan fork that this repository started from. Two generator lineages therefore sit side by side in one tree, and the README does not say when each is selected or whether one is on the way out. If you are evaluating the design, that is the first question to ask the maintainers, because it decides what you are signing up to maintain.

For the cryptography itself, the README points at three primary sources: the Jolt paper on lookups for virtual machines, the Lasso paper on the lookup argument, and Twist and Shout on memory checking through one-hot addressing and increments. The August 18, 2025 blog post announces the Twist and Shout upgrade, under a path that names a 6x speedup, though the README itself offers no benchmark table to check that figure against.

Editorial conclusion

Engineers prototyping zero-knowledge proofs in Rust can use Jolt now to get a real prover running on an RV64IMAC guest, and the pinned toolchain plus the quickstart guide in the Jolt Book are enough to do it. Teams that need audited code, a stable public interface, or any production guarantee should look elsewhere, because the project states Jolt is in alpha and is not suitable for production use at this time. Before depending on it, check your guest's instruction needs against the RV64IMAC list, and confirm which crate version you are pinning, since Cargo.toml still reads 0.1.0 while the tagged releases are v0.2.1-alpha, v0.2.2-alpha and v0.3.0-alpha. The last push was on 2026-10-15, so the tree moves quickly.

Frequently asked questions

Is Jolt ready for production use?

No. The README states that Jolt is in alpha and is not suitable for production use at this time, and every tagged release carries an alpha suffix. The last push was on 2026-10-15, so the code moves, but stability is not being claimed.

What RISC-V instruction set does Jolt support?

The current implementation covers the RISC-V 64-bit Base Integer Instruction Set, the M extension for integer multiplication and division, the A extension for atomic operations, and the C extension for compressed instructions, which is RV64IMAC. 32-bit guests and floating point are not part of that list.

How do I install the Jolt CLI?

Clone the repository and let rustup install the toolchain pinned in rust-toolchain.toml, then install the CLI from the checkout with cargo install --path. Running rustup show inside the cloned directory confirms the correct toolchain was picked.

Can I attach a debugger to a Jolt guest program?

No. The README says Tracer, Jolt's emulator, does not currently support attaching a debugger. It supports backtraces for guest panics, with symbol resolution enabled by JOLT_BACKTRACE=1 or the full variant for register snapshots and cycle counts.

How do I profile the Jolt prover's memory usage?

Run the prover with the profiling and allocative features and request the chrome format, which writes a timestamped directory under benchmark-runs containing trace.json, summary.json and memory.html. Heap totals come from per-batch snapshots of the live sumcheck state and appear in summary.json.

Official sources

  1. a16z/jolt on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/a16z-jolt.svg)](https://hysenlabs.com/projects/a16z-jolt)

Was this useful?