Arbitrum Nitro: a Go and Rust optimistic rollup stack
Nitro goes vroom and fixes everything
At a glance
- What is it?
- Arbitrum Nitro is the layer 2 rollup system behind Arbitrum One, built as a Go node with a Rust prover that runs Geth compiled to WASM. It is licensed under a Business Source License with an Additional Use Grant, and the repository mixes Go, Rust, Solidity and a vendored go-ethereum tree.
- Who is it for?
- Nitro is a serious fit for teams operating rollup infrastructure, bridges, fraud proof machinery or Stylus contracts, and it is the wrong tool for an application team that only needs a cheap place to deploy a contract.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.
Star history
- OffchainLabs/nitro970 ★ · +10
| Repository | 2026-10-21 | 2026-11-07 |
|---|---|---|
| OffchainLabs/nitro | 960 | 970 |
10 Stars in the last 17 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
Nitro is the whole layer 2 system, not a component of one
The readme describes Nitro as the latest iteration of the Arbitrum technology and calls it a fully integrated, complete layer 2 optimistic rollup system. The list it gives is the interesting part: fraud proofs, the sequencer, the token bridges, advanced calldata compression. So this repository is not a library you link into an application. It is the chain.
The historical context matters for reading the code. Arbitrum One migrated from the Classic Arbitrum stack onto Nitro on 8/31/22, and the readme links to state migration and dapp migration documentation for that transition. The default branch is `master`, and the last push was on 2026-10-16, with three releases, v3.12.1, v3.12.0 and v3.11.5, all published on 2026-10-02. Publishing a patch on two different minor branches on the same day suggests the release process tracks maintenance lines in parallel.
For the reader, the practical shape is this: the repository is a monorepo of a Go node, a Rust prover, contract sources, tooling and a vendored copy of go-ethereum. The go.mod file declares `replace github.com/ethereum/go-ethereum => ./go-ethereum`, so the Ethereum client is built from the tree inside this repository rather than pulled from upstream. You are not choosing between Geth versions here, you are compiling the one that ships with the release.
Geth compiled to WASM replaces the custom EVM emulator
The central technical claim in the readme is about the prover. Nitro's prover performs Arbitrum's classic interactive fraud proofs over WASM code, which means the layer 2 engine can be written and compiled with standard languages and tools, replacing the custom designed language and compiler used in earlier Arbitrum versions. The readme states it directly: Nitro runs Geth at layer 2 on top of Ethereum and can prove fraud over the core engine of Geth compiled to WASM.
The execution model follows from that. In normal operation, validators and nodes run the Nitro engine compiled to native code. If a fraud proof becomes necessary, they switch to WASM. So the fast path is a native binary and the dispute path is an interpreter, and the two paths have to agree on state transitions, which is exactly what the fraud proof machinery exists to check.
Because the core of Geth is compiled in, the previous custom built EVM emulator is replaced by Geth itself, which the readme calls the most popular and well supported Ethereum client. The consequence for anyone extending the chain is direct. Ethereum tooling, Ethereum libraries and Ethereum semantics apply at layer 2, and the gap between what a chain developer knows about Ethereum and what they need to know about Arbitrum narrows considerably.
ArbOS in Go handles messaging, batching and compression
The other half of the stack is a slimmed down version of ArbOS, rewritten in Go, which the readme says provides the rest of what is needed to run a layer 2 chain: cross chain communication, and a new and improved batching and compression system to minimise layer 1 costs.
In the repository layout this shows up as top level directories with clear roles. `arbos/` is the Go component, `arbnode/` is the node, `arbutil/` holds shared Go utilities, `arbstate/` covers state, and `arbcompress/` is the compression piece. There is also a `relay/` directory for message passing between layers and a `blocks_reexecutor/` directory, which is the kind of name you give code that replays blocks.
Batching and compression matter because layer 1 data cost is the bill for a rollup. Arbitrum's approach is to compress transaction data before posting it to Ethereum, and the Cargo workspace includes `crates/wasm-libraries/arbcompress` alongside `crates/brotli` and a `brotli` directory at the top level, with a dedicated build script. The Dockerfile goes further and compiles Brotli to WASM through the Emscripten SDK in a stage named `brotli-wasm-builder`, pinning both a branch of emsdk and a commit hash before installing the SDK version.
Arbitrum Classic also continues to be supported, and only the ArbOS release activated on mainnet Arbitrum One receives security updates and urgent vulnerability patches. Both of those statements shape what you must run today.
The Rust workspace holds the prover, the validator and Stylus
The Cargo.toml declares a workspace whose default members are `crates/jit` and `crates/prover`, with a broader member list that includes `crates/validator`, `crates/bench`, `crates/caller-env`, `crates/validation`, `crates/prover-ffi`, `crates/stylus` and a set of `crates/wasm-libraries/` packages such as `arbcompress`, `arbcrypto`, `host-io`, `program-exec` and `user-host`.
Read those names as a description of the execution pipeline. The JIT compiles and runs native code for the fast path, the prover handles the interactive fraud proof, the validator checks one step of execution against the rules, and the wasm-libraries implement the host interface that contracts see when they make calls out of the sandbox. `crates/stylus` is the home of Stylus, the Rust based contract toolchain, and `crates/prover-ffi` is the boundary between the Rust prover and the Go node, which matters because the two languages sit on either side of that interface.
The workspace is pinned aggressively. The workspace package declares `edition = "2024"` and `rust-version = "1.93"`, and the dependency list uses exact versions for several crates, including `alloy-rpc-types-engine = { version = "=1.6.3" }`. The Go side is similarly strict: go.mod requires `go 1.25` with `toolchain go1.25.12`, and the Makefile stamps build metadata into the binary through linker flags for `NITRO_TAG`, `NITRO_BRANCH`, `NITRO_COMMIT`, `NITRO_DATETIME` and `NITRO_MODIFIED`.
There is also a `bold/` directory, a `daprovider/` directory and a `nitro-reth/` directory in the tree, plus a `CHANGELOG.md` and a `changelog/` directory at the top level, so change history is tracked inside the repository rather than only in release notes.
Building the stack means Node, Foundry, Emscripten, Go and Rust
The readme does not give an install command for running a node, and it points to the live documentation site at developer.arbitrum.io instead, with a separate repository holding the markdown source of the docs. There is no copy and paste path here, and anyone planning a deployment needs to read those docs.
What the repository does show is the build environment. The Dockerfile is a multi stage build on `debian:bookworm-slim`. It builds Brotli to WASM and to a native library, using cmake, make, gcc and the Emscripten SDK, with a separate `brotli-wasm-export` stage that copies the result out of a `scratch` image. Contract compilation runs on `node:24.4.1-bookworm-slim`, installs Foundry with a pinned `foundryup -i 1.2.3`, and runs `yarn install` for `contracts-legacy` and `contracts`, with separate directories for `contracts-local` and `safe-smart-account`.
The Makefile is where the version metadata is injected. Setting `NITRO_TAG`, `NITRO_BRANCH` or `NITRO_COMMIT` adds linker flags that write those values into `nitroversion`, so a binary reports exactly which source it came from. There is a stripped build mode as well, where `STRIP=1` adds `-s -w` to the Go linker flags and switches cargo to the stripped profile, used by the `nitro-node-*-stripped` Docker targets.
The build therefore needs several toolchains that are not interchangeable, and the repository carries a `.nvmrc`, a `rust-toolchain.toml` and a `.golangci.yml` to pin them.
A business source licence with a permissionless use grant
Nitro is licensed under a Business Source License, held in LICENSE.md, and the readme compares that arrangement to the ones used by Uniswap and Aave. Two additional pieces of paperwork modify what you can do with the code.
The Additional Use Grant exists to make sure that everyone can run nodes on all public Arbitrum chains, and it also permits deploying the Nitro software permissionlessly and without cost as a new blockchain, provided that the chain settles to either Arbitrum One or Arbitrum Nova. So the default case, a chain that settles back to Arbitrum, carries no revenue condition.
The Arbitrum Expansion Program is the other path. For a deployment that settles directly on Ethereum as a layer 2, or that settles to another layer 2 on top of Ethereum, the AEP terms apply, and the readme states that 10% of net revenue, as described in the AEP, must be contributed back to the Arbitrum community under the requirements of that programme.
That is the line to read carefully. Settling to Arbitrum One or Nova is permissionless and free. Settling elsewhere brings a revenue share and a set of contractual terms. This is a licensing condition rather than legal advice, and anyone planning a chain launch needs the AEP document itself, which is linked from the readme as a PDF of terms.
Support windows are short and only one ArbOS version gets patches
The support policy is unusually concrete. The current minor release of Nitro is always supported. Older versions are supported until the earlier of two conditions: 30 calendar days have passed since the version was released and a newer minor release exists, or Offchain Labs communicates a critical security concern that warrants immediate upgrading to a fixed version.
The second condition is the one that changes how you operate. A version can be out of support almost immediately if a critical issue is flagged, and there is no long deprecation runway. In practice that means a node operator has to be able to move to the current minor release on short notice rather than scheduling an annual upgrade.
ArbOS has a tighter rule still. Only the ArbOS release activated on mainnet Arbitrum One receives security updates and urgent vulnerability patches, and the readme strongly recommends staying up to date with the latest ArbOS for that reason. There is a documented way to check which version is live: call the `arbOSVersion()` method on the `ArbSys` precompile at address `0x000....64`. The result needs an offset of 55, because the first version of Nitro is known as version 56, so a response of 106 indicates ArbOS version 51.
That offset is a small trap for anyone building monitoring. Activation timestamps for ArbOS upgrades on Arbitrum One are published on a network upgrades page, with the most recent entry being the version actively in use, which gives you the reference value to compare the on-chain call against.
Where Nitro is the wrong tool
The clearest case is the majority of application developers. If you want to deploy a contract and pay layer 2 gas, you do not need this repository, you need a deployment against a chain that already runs Nitro, and the operational work of running nodes, bridges and a sequencer is not something an application team should take on.
Even for infrastructure teams, the burden is heavy. Building from source means Node with a pinned Foundry, the Emscripten SDK with a pinned commit, a Rust toolchain at version 1.93 or newer, and Go 1.25 with a pinned toolchain, plus a vendored go-ethereum that has to be built as part of the tree. Each of those is a separate supply chain to track.
There are limits that come from the design itself. Fraud proofs over WASM mean the dispute path is slower than the native path, and the readme is explicit that nodes switch to WASM only when a fraud proof is needed. A chain that inherits Geth inherits Geth's semantics, which is a benefit for compatibility and a constraint on customising execution. And the ArbOS patching rule means a chain operator cannot choose which ArbOS version to run for safety reasons: only the version activated on Arbitrum One receives security updates.
The readme also does not document a rollback procedure, a documented upgrade ordering between node and ArbOS versions, or the operator runbook for the sequencer. Those live in the linked documentation, and the separation between a sparse readme and an external documentation site is the main practical friction in evaluating the project from the repository alone.
Editorial conclusion
Nitro is a serious fit for teams operating rollup infrastructure, bridges, fraud proof machinery or Stylus contracts, and it is the wrong tool for an application team that only needs a cheap place to deploy a contract. Before using it, read LICENSE.md together with the Additional Use Grant and the Arbitrum Expansion Program terms, because a new chain settling to Ethereum rather than to Arbitrum One or Nova falls under the AEP revenue terms, and check `arbOSVersion()` on the `ArbSys` precompile to confirm the ArbOS version your node expects against the version activated on Arbitrum One.
Frequently asked questions
What is Arbitrum Nitro?
It is the layer 2 optimistic rollup system behind Arbitrum, described as a fully integrated stack that includes fraud proofs, the sequencer, the token bridges and advanced calldata compression. Arbitrum One migrated from the Classic Arbitrum stack onto Nitro on 8/31/22.
How does Nitro run the Ethereum Virtual Machine?
The readme says the core of Geth is compiled right into Arbitrum, so the previous custom built EVM emulator is replaced by Geth. The engine runs as native code in normal operation and switches to WASM when a fraud proof is needed.
Under what licence is Arbitrum Nitro released?
It is licensed under a Business Source License with an Additional Use Grant that permits permissionless deployment of a new chain settling to Arbitrum One or Arbitrum Nova. A chain settling directly to Ethereum or to another layer 2 falls under the Arbitrum Expansion Program, which requires contributing 10% of net revenue to the Arbitrum community.
How do I check which ArbOS version is active on Arbitrum One?
Call the `arbOSVersion()` method on the `ArbSys` precompile at `0x000....64`. The response needs an offset of 55 applied, since the first Nitro version is known as version 56, so a response of 106 means ArbOS version 51.
How long are older Arbitrum Nitro releases supported?
The current minor release is always supported. An older version is supported until either 30 calendar days have passed since its release and a newer minor release exists, or Offchain Labs communicates a critical security concern about it that warrants an immediate upgrade.
Official sources
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.
[](https://hysenlabs.com/projects/offchainlabs-nitro)Star history chart for your README
[](https://hysenlabs.com/projects/offchainlabs-nitro)Was this useful?