Configuration reference
A Stylus Rust project uses three configuration files:
| File | Purpose |
|---|---|
Stylus.toml | Marks a package as a Stylus contract and stores deployment metadata |
Cargo.toml | Defines dependencies, feature flags, library targets, and build profile |
rust-toolchain.toml | Pins the Rust compiler version and WebAssembly compilation target |
Running cargo stylus new <project> generates all three files with sensible defaults. The sections below document every Stylus-specific option you can configure.
Stylus.toml
Stylus.toml serves two purposes:
- Contract marker —
cargo stylusidentifies a package as a Stylus contract by the presence of this file alongsideCargo.toml. Without it, the package is ignored during workspace builds and deployments. - Deployment metadata — Stores per-contract deployment records and, at the workspace level, network endpoint definitions.
Contract-level Stylus.toml
Place this file in the root of each contract package (next to Cargo.toml).
[contract]
[contract.deployments.my-deployment]
network = "arbitrum-sepolia"
no_activate = false
deployer_address = "0x1234567890abcdef1234567890abcdef12345678"
[contract] section
The [contract] table is required. It can be empty — its presence marks the package as a Stylus contract.
[contract.deployments.<name>] section
Each named deployment stores a record of where and how the contract was deployed.
| Key | Type | Description |
|---|---|---|
network | string | Network identifier matching a [workspace.networks] entry or a well-known network name |
no_activate | bool | If true, the contract was deployed without activation. Default: false |
deployer_address | address | The Ethereum address (checksummed hex) of the account that deployed the contract |
Workspace-level Stylus.toml
Place this file at the root of a Cargo workspace to define shared network configuration.
[workspace]
[workspace.networks.arbitrum-sepolia]
endpoint = "https://sepolia-rollup.arbitrum.io/rpc"
[workspace.networks.arbitrum-one]
endpoint = "https://arb1.arbitrum.io/rpc"
[workspace] section
The [workspace] table is required. It can be empty.
[workspace.networks.<name>] section
Define named networks that contracts in the workspace can reference.
| Key | Type | Description |
|---|---|---|
endpoint | string | RPC endpoint URL for the named network |
Cargo.toml
Standard Rust manifest with Stylus-specific sections. The cargo stylus new command generates these defaults automatically.
[lib]
Stylus contracts must compile as both a Rust library and a C-compatible dynamic library (for WASM export):
[lib]
crate-type = ["lib", "cdylib"]
libenables standard Rust imports and testing.cdylibproduces the WebAssembly binary that gets deployed onchain.
Removing cdylib from crate-type prevents the contract from compiling to WASM. Removing lib prevents running tests and exporting ABI.
[dependencies]
At minimum, a Stylus contract requires stylus-sdk:
[dependencies]
stylus-sdk = "0.10.2"
alloy-primitives = "1.5.7"
alloy-sol-types = "1.5.7"
The alloy-primitives and alloy-sol-types crates are transitive dependencies of stylus-sdk but are typically listed explicitly when your contract uses Ethereum types (Address, U256, sol! macro) directly.
[features]
Feature flags control compilation behavior. The defaults generated by cargo stylus new:
[features]
default = ["mini-alloc"]
export-abi = ["stylus-sdk/export-abi"]
debug = ["stylus-sdk/debug"]
mini-alloc = ["stylus-sdk/mini-alloc"]
contract-client-gen = []
| Feature | Purpose |
|---|---|
mini-alloc | Uses a minimal memory allocator optimized for contract binary size. Enabled by default. |
export-abi | Generates a Solidity-compatible ABI via cargo stylus export-abi. Enables debug automatically. |
debug | Enables console! logging for local debugging. Has no effect in onchain execution. |
contract-client-gen | Reserved for tooling that generates Solidity interface contracts from Rust source. |
SDK features
These features are defined in the stylus-sdk crate and can be enabled via stylus-sdk/feature-name syntax in your [features] section:
| Feature | Purpose |
|---|---|
stylus-test | Enables the TestVM testing framework for writing unit tests without a blockchain. |
reentrant | Enables reentrancy support for contracts that need to make external calls that call back. |
hostio | Exposes low-level host I/O function signatures for advanced use cases. |
Example enabling stylus-test for development:
[dev-dependencies]
stylus-sdk = { version = "0.10.2", features = ["stylus-test"] }
[profile.release]
The release profile controls how the WASM binary is compiled. These defaults optimize for small binary size:
[profile.release]
codegen-units = 1
strip = true
lto = true
panic = "abort"
opt-level = 3
| Key | Default | Description |
|---|---|---|
codegen-units | 1 | Compile the entire crate as a single unit for maximum optimization. |
strip | true | Remove debug symbols and metadata from the binary. |
lto | true | Enable link-time optimization across all crates. |
panic | abort | Use immediate abort on panic instead of unwinding (smaller binary). |
opt-level | 3 | Optimize for speed. Use "s" or "z" to optimize for binary size instead. See Optimizing binaries for guidance. |
If your contract exceeds the 24KB compressed size limit, change opt-level to "z" for maximum size reduction. This typically produces smaller binaries at the cost of some runtime performance.
rust-toolchain.toml
Pins the Rust compiler version and ensures the WASM compilation target is installed:
[toolchain]
channel = "1.91.0"
targets = ["wasm32-unknown-unknown"]
| Key | Description |
|---|---|
channel | Rust compiler version. Used by block explorers for deterministic source verification. |
targets | Must include wasm32-unknown-unknown for Stylus contracts. Additional targets can be listed for local testing. |
Changing the Rust version may affect source code verification on block explorers like Arbiscan. Pin to a specific stable version rather than using stable or nightly.
Complete examples
Single contract
A minimal Stylus contract project:
my-contract/
├── src/
│ ├── lib.rs
│ └── main.rs
├── Cargo.toml
├── Stylus.toml
└── rust-toolchain.toml
Stylus.toml
[contract]
Cargo.toml
[package]
name = "my-contract"
version = "0.1.0"
edition = "2021"
[dependencies]
stylus-sdk = "0.10.2"
alloy-primitives = "1.5.7"
alloy-sol-types = "1.5.7"
[dev-dependencies]
stylus-sdk = { version = "0.10.2", features = ["stylus-test"] }
[features]
default = ["mini-alloc"]
export-abi = ["stylus-sdk/export-abi"]
debug = ["stylus-sdk/debug"]
mini-alloc = ["stylus-sdk/mini-alloc"]
[lib]
crate-type = ["lib", "cdylib"]
[profile.release]
codegen-units = 1
strip = true
lto = true
panic = "abort"
opt-level = "z"
rust-toolchain.toml
[toolchain]
channel = "1.91.0"
targets = ["wasm32-unknown-unknown"]
Workspace with multiple contracts
A workspace containing two contracts with shared network configuration:
my-workspace/
├── contracts/
│ ├── token/
│ │ ├── src/
│ │ ├── Cargo.toml
│ │ └── Stylus.toml
│ └── governance/
│ ├── src/
│ ├── Cargo.toml
│ └── Stylus.toml
├── crates/
│ └── shared-lib/
│ ├── src/
│ └── Cargo.toml
├── Cargo.toml
├── Stylus.toml
└── rust-toolchain.toml
Workspace Stylus.toml
[workspace]
[workspace.networks.arbitrum-sepolia]
endpoint = "https://sepolia-rollup.arbitrum.io/rpc"
[workspace.networks.arbitrum-one]
endpoint = "https://arb1.arbitrum.io/rpc"
Workspace Cargo.toml
[workspace]
resolver = "2"
members = ["contracts/*", "crates/*"]
Contract Stylus.toml (in contracts/token/)
[contract]
[contract.deployments.sepolia]
network = "arbitrum-sepolia"
no_activate = false
deployer_address = "0x1234567890abcdef1234567890abcdef12345678"
Note that crates/shared-lib/ does not have a Stylus.toml because it is a shared Rust library, not a deployable contract. Only packages with a Stylus.toml are treated as contracts by cargo stylus.