Library / SDK
iden3/snarkjs avatar
iden3/snarkjs

snarkjs: zkSNARK proof generation and verification in JavaScript and WebAssembly

zkSNARK implementation in JavaScript & WASM

2,040 stars488 forksJavaScriptGPL-3.0

At a glance

What is it?
snarkjs is a JavaScript and pure WebAssembly implementation of the Groth16, PLONK and FFLONK zero-knowledge proof schemes, including the full trusted setup ceremony tooling. It runs in Node.js and in browsers, and its maximum circuit size is capped at 2^28 constraints.
Who is it for?
snarkjs is the right tool for teams who need zkSNARK proof generation and verification in a JavaScript runtime without compiling a native binary, and for projects building on circom circuits. It is a poor fit for circuits that exceed 2^28 constraints, and its GPL-3.0 licence creates a compatibility question for proprietary applications that the licence text must answer.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 10 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

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

Editorial analysis

zkSNARK proof generation in JavaScript with no native binary

Zero-knowledge proofs typically require a native implementation in C++ or Rust, because the elliptic curve operations involved are computationally intensive. snarkjs moves that work into WebAssembly and runs it in both Node.js and the browser, with no compiled binary to distribute or platform-specific dependency to manage.

The library's intended users are developers building on circom circuits, which is the circuit compiler in the same iden3 ecosystem. A circom-compiled circuit produces the input snarkjs needs for proving and verification. Anyone using a different circuit compiler would need to check whether its output format is compatible.

snarkjs also includes the full tooling for trusted setup ceremonies, which are a prerequisite for Groth16 and PLONK proofs. Running a ceremony, participating in one, verifying it, and applying a final public randomness contribution are all subcommands inside the same package. That makes it possible to go from a fresh Node.js install to a complete ceremony transcript with a single tool.

Groth16, PLONK and FFLONK: three proof systems with different trust requirements

snarkjs implements three proof systems. Groth16 uses 3 points and 3 pairings and requires a circuit-specific trusted setup, meaning a new phase 2 ceremony for every change to the circuit. PLONK and FFLONK share the phase 1 universal setup, so circuit changes only require a new key derivation rather than a full new ceremony.

The choice between them affects operational cost, not just performance. A team that ships a stable circuit can use Groth16 and accept the per-circuit setup cost. A team that iterates on the circuit would benefit from PLONK or FFLONK, since the universal powers of tau file can be reused across circuit versions. Proof sizes and verification times across the three schemes are not compared in any table in the documentation.

The low-level curve arithmetic runs in WASM and uses worker threads to parallelize the work. Performance is described as comparable to native host implementations, but no specific benchmarks or named comparison targets appear in the project, so that claim cannot be verified from the repository alone.

Installing snarkjs and starting the first powers of tau ceremony

snarkjs installs as a global CLI via npm. Node.js v18 or newer is required; earlier versions are described as not guaranteed to work:

sh
npm install -g snarkjs@latest

After installation, the help command lists all subcommands:

sh
snarkjs --help

Every subcommand also has a shorter alias. The Groth16 prove command, for example, is available as both `snarkjs groth16 prove` and `snarkjs g16p`. Adding `-v` or `--verbose` to any command shows progress detail, which is useful when a command is taking longer than expected.

A first powers of tau ceremony starts with the `new` command:

sh
snarkjs powersoftau new bn128 14 pot14_0000.ptau -v

This creates pot14_0000.ptau for the bn128 curve, sized for circuits with up to 2^14 (16,384) constraints. The second parameter is the exponent, not the count: a circuit with more constraints than 2^14 needs a higher exponent, and the exponent must be chosen before the ceremony starts. The supported curve types are bn128 and bls12-381.

How each contribution to the ceremony adds to the ptau transcript

Each contribution to the powers of tau ceremony takes the previous ptau file as input and produces a new one. The first contribution looks like this:

sh
snarkjs powersoftau contribute pot14_0000.ptau pot14_0001.ptau --name="First contribution" -v

The command prompts for random text, which becomes extra entropy. To make the step non-interactive, pass the `-e` option:

sh
snarkjs powersoftau contribute pot14_0001.ptau pot14_0002.ptau --name="Second contribution" -v -e="some random text"

Each ptau file carries the complete history of challenges and responses up to that point. The `verify` command checks the full chain:

sh
snarkjs powersoftau verify pot14_0003.ptau

A clean verification prints "[INFO] snarkJS: Powers Of tau file OK!" to the console. After all contributions are in, the ceremony finishes with a final randomness contribution from a public source:

sh
snarkjs powersoftau beacon pot14_0003.ptau pot14_beacon.ptau 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 10 -n="Final Beacon"

The randomness value must be public and high-entropy, and possible sources named for this step include: the closing value of a stock market on a future date, national lottery outputs, or the hash of a specific blockchain block.

The 2^28 constraint ceiling and why the ptau size must match the circuit

The maximum power supported is 28, which means the largest possible ptau file covers circuits with up to 2^28 constraints (approximately 268 million). That ceiling is a hard limit of the scheme, not a configuration option.

The power you choose when starting a ceremony determines the maximum constraint count of any circuit that can use the resulting ptau file. A circuit that exceeds the ptau's ceiling cannot proceed to phase 2 setup. Working out the constraint count of a circom circuit requires compiling it first; the count is not visible from the .circom source alone.

This creates a practical sequencing problem. A team that starts a ceremony for power 14 and later discovers their circuit needs power 17 has to restart the ceremony. Running a ceremony at a larger power than needed wastes time, since the computation scales with the exponent. Checking the compiled circuit's constraint count before selecting the power is a necessary first step that the documentation leaves unstated.

Using an existing community ceremony to skip phase 1 entirely

snarkjs supports interoperability with external ceremony outputs. The file formats used in the library are compatible with Semaphore's Perpetual Powers of Tau and with kobigurk/phase2-bn254. That means any project can start its circuit-specific phase 2 ceremony from a ptau file produced by one of those external ceremonies rather than running phase 1 itself.

Any zk-snark project can pick a round from the common phase 1 to start their circuit-specific phase 2 ceremony. In practice, a team can download a ptau file from an established ceremony and verify it with `snarkjs powersoftau verify` before using it as the starting point for their own phase 2. Skipping phase 1 saves time and avoids the need to recruit contributors for the universal setup.

The trust model is different: you are trusting that at least one contributor to the external ceremony was honest, not that your own contributors were. How the security assumptions differ between running your own phase 1 and using a community one is not compared in the project documentation.

Four build targets in package.json and how to import the library in a browser

The package.json exports map shows four output builds, and the right one to import depends on the runtime. For Node.js with import syntax, the target is main.js. For Node.js projects that use require() instead, the CommonJS build at build/main.cjs is the correct entry point. For browser-based bundler projects (using Rollup or Webpack), the target is build/browser.esm.js. For direct browser loading without a bundler, the target is build/snarkjs.min.js, which is built as a UMD module.

This distinction matters in practice. A developer who imports snarkjs with a bundler expecting the main.js path may get the Node.js build rather than the browser-optimized one, and the WASM module paths inside differ. The package.json exports map handles this automatically when the bundler respects the "browser" and "umd" conditions; bundlers that do not read the exports map need the path set explicitly.

The last push was on 2026-10-01, the most recent release is v0.7.6 from 2026-01-26, and the project is licensed under GPL-3.0.

Editorial conclusion

snarkjs is the right tool for teams who need zkSNARK proof generation and verification in a JavaScript runtime without compiling a native binary, and for projects building on circom circuits. It is a poor fit for circuits that exceed 2^28 constraints, and its GPL-3.0 licence creates a compatibility question for proprietary applications that the licence text must answer. Before depending on it, verify that your circuit's constraint count falls within the limit supported by the powers of tau file you plan to use, because a mismatch between the ptau ceiling and the compiled circuit will cause the setup to fail.

Frequently asked questions

What is snarkjs?

snarkjs is a JavaScript and WebAssembly library for generating and verifying zero-knowledge proofs using the Groth16, PLONK and FFLONK schemes. It includes the full tooling for trusted setup ceremonies and works in both Node.js and browsers.

How do I install snarkjs?

Run npm install -g snarkjs@latest to install it as a global CLI. Node.js v18 or newer is required. Circom must be installed separately if you plan to compile circuits.

What is the maximum circuit size snarkjs supports?

The maximum power supported is 28, corresponding to circuits with up to 2^28 constraints (approximately 268 million). The power is set when starting a powers of tau ceremony and cannot be changed after the fact.

Does snarkjs work in a browser?

Yes. The package.json exports map provides a browser ESM build at build/browser.esm.js and a minified UMD build at build/snarkjs.min.js. It is described as an ES module compatible with Rollup and Webpack.

What curves does snarkjs support?

snarkjs supports the bn128 and bls12-381 curves. The curve type is specified when starting a powers of tau ceremony.

Official sources

  1. iden3/snarkjs on GitHub
  2. Issues
  3. License: GPL-3.0
  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/iden3-snarkjs.svg)](https://hysenlabs.com/projects/iden3-snarkjs)