Stylus lets you write Arbitrum smart contracts in Rust (and any language that compiles to WASM, including C and C++) and have them execute alongside Solidity contracts in the same EVM state. Programs are compiled with `cargo stylus`, deployed as brotli-compressed WASM, then 'activated' on-chain — the Stylus SDK is built on top of Alloy and exposes ABI-compatible interfaces that Solidity contracts can call directly.
- 01compute-heavy contracts (cryptography, numerics) where WASM beats EVM gas
- 02porting existing Rust crates on-chain
- 03mixed Solidity + Rust codebases on Arbitrum One / Nova / Orbit
- 04C / C++ smart contracts via WASM toolchains
- cargo install --force cargo-stylus
- cargo stylus new my-stylus-contract
| Variable | Scope | Description |
|---|---|---|
| STYLUS_RPC_URL | Client | Arbitrum RPC URL — Arbitrum One, Sepolia, Nova, or your Orbit chain (must have Stylus enabled). |
| STYLUS_PRIVATE_KEY | Server | Deployer private key used by `cargo stylus deploy` (server-side / CI only). |
Install the toolchain with `cargo install --force cargo-stylus` and scaffold a project via `cargo stylus new my-contract`. Write contracts using the Stylus SDK — annotate storage with `#[storage]` and entrypoints with `#[public]` (and `#[entrypoint]` on the root struct). Validate the binary deploys and activates with `cargo stylus check --endpoint $STYLUS_RPC_URL`. Deploy and activate in one shot with `cargo stylus deploy --endpoint $STYLUS_RPC_URL --private-key $PK` (or split into deploy + activate). Export a Solidity ABI for cross-language interop with `cargo stylus export-abi` so Solidity contracts and TypeScript clients (viem/ethers) can call your Rust contract through the standard ABI. Stylus is live on Arbitrum One, Sepolia, Nova, and any Orbit chain that has it enabled at deploy.
- ⚑Stylus uses an `ink` gas accounting model in addition to EVM gas — fee estimation libraries built for pure EVM mis-price Stylus calls. Use the chain's Stylus-aware estimator (`cargo stylus estimate-gas` or the Arbitrum precompiles) and surcharge the EVM estimate when calling from Solidity.
- ⚑Contracts must be 'activated' after deployment in a separate transaction (or via the `--activate` flag); deployed-but-unactivated contracts revert on call. Activations also expire and may need to be renewed after ~365 days of inactivity — schedule re-activation for long-lived contracts.
- ⚑ABI-compatibility with Solidity is best-effort — complex types (multi-dimensional arrays, custom errors, certain enum encodings) sometimes serialize differently. Always run a cross-language integration test rather than trusting `export-abi` blindly.
- ⚑Stylus is only available on chains that have it enabled — Arbitrum One, Sepolia, Nova, and Orbit chains that opted in at deploy time. A vanilla EVM chain or an OP Stack rollup will not run WASM bytecode.
- ⚑Compiled WASM has a code-size limit (currently ~24 KB compressed, similar to EVM's 24 KB cap but applied to the brotli-compressed WASM). Large Rust crates can blow this; lean on `no_std`, strip panics, and use workspace patterns (Stylus SDK v0.10+) to split logic across contracts.
- ⚑The sequencer trust model is Arbitrum's — Stylus does not change it. Centralized sequencer, 7-day challenge window for L1 withdrawals on Arbitrum One; on an Orbit chain you inherit whatever the operator chose. Force-inclusion via the L1 inbox is the canonical fallback.
- ⚑Cross-contract calls between Stylus and Solidity work but must use the SDK's `Call` / `RawCall` types or generated `#[public]` trait clients (SDK v0.10) — naively `extern`-ing a Solidity ABI from Rust without going through Alloy's encoder produces silent calldata mismatches.