Skip to main content

Configuration reference

A Stylus Rust project uses three configuration files:

FilePurpose
Stylus.tomlMarks a package as a Stylus contract and stores deployment metadata
Cargo.tomlDefines dependencies, feature flags, library targets, and build profile
rust-toolchain.tomlPins 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:

  1. Contract markercargo stylus identifies a package as a Stylus contract by the presence of this file alongside Cargo.toml. Without it, the package is ignored during workspace builds and deployments.
  2. 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.

KeyTypeDescription
networkstringNetwork identifier matching a [workspace.networks] entry or a well-known network name
no_activateboolIf true, the contract was deployed without activation. Default: false
deployer_addressaddressThe 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.

KeyTypeDescription
endpointstringRPC 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"]
  • lib enables standard Rust imports and testing.
  • cdylib produces the WebAssembly binary that gets deployed onchain.
caution

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 = []
FeaturePurpose
mini-allocUses a minimal memory allocator optimized for contract binary size. Enabled by default.
export-abiGenerates a Solidity-compatible ABI via cargo stylus export-abi. Enables debug automatically.
debugEnables console! logging for local debugging. Has no effect in onchain execution.
contract-client-genReserved 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:

FeaturePurpose
stylus-testEnables the TestVM testing framework for writing unit tests without a blockchain.
reentrantEnables reentrancy support for contracts that need to make external calls that call back.
hostioExposes 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
KeyDefaultDescription
codegen-units1Compile the entire crate as a single unit for maximum optimization.
striptrueRemove debug symbols and metadata from the binary.
ltotrueEnable link-time optimization across all crates.
panicabortUse immediate abort on panic instead of unwinding (smaller binary).
opt-level3Optimize for speed. Use "s" or "z" to optimize for binary size instead. See Optimizing binaries for guidance.
tip

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"]
KeyDescription
channelRust compiler version. Used by block explorers for deterministic source verification.
targetsMust include wasm32-unknown-unknown for Stylus contracts. Additional targets can be listed for local testing.
caution

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.