Reference implementation

The prover, live

Every idea in this catalog compiles down to something like this: a few lines of Noir, an UltraHonk proof, and a verifier that learns only what the circuit chose to make public. No server, no account, no upload.

Loading the live prover…

What it costs
load90scompiler + prover wasm, tens of MB, then HTTP-cached
compilesecondsNoir source → ACIR, in memory
witness30scheap for a small circuit
prove180sUltraHonk, one thread — dominates everything
verify60sfast, but still bounded

Each phase carries its own timeout. An unbounded await is indistinguishable from a silently hung WebAssembly instantiation.

The two traps
  1. Never pre-bundle the proving stack. Add all three packages to optimizeDeps.exclude or esbuild rewrites the wasm-bindgen glue and instantiation hangs with no error.
  2. Serve noir_wasm’s browser bundle verbatim. Re-processing it emits const Infinity = Infinity, so the compiler throws “Cannot access ’j’ before initialization” — in production only.

Both are wired into this project’s vite.config.ts, with the reasoning in the comments. The three packages are pinned together: noir_wasm and noir_js on the same beta, bb.js on a version that speaks their ACIR.