How to Configure Build Profiles and Optimization Levels in Sway: A Complete Guide
Sway projects use [build-profile] tables in Forc.toml to bundle compiler flags and optimization levels, where optimization_level = 0 disables IR passes for faster builds and optimization_level = 1 enables full optimizations for production.
The Sway compiler (forc) controls the compilation pipeline through build profiles defined in your project's manifest. By configuring these profiles, you can switch between rapid debug iterations with no optimizations and release builds that run aggressive IR passes to minimize bytecode size. This guide covers how to configure build profiles and optimization levels in Sway using the manifest format and CLI overrides, based on the actual implementation in the FuelLabs/sway repository.
Understanding Build Profiles in Sway
A build profile is a named collection of compiler settings stored under [build-profile.<name>] in Forc.toml. According to forc-pkg/src/manifest/build_profile.rs, profiles deserialize into BuildProfile structs containing fields like optimization_level, print_asm, and backtrace.
The compiler automatically injects two default profiles—debug and release—if you don't define them explicitly. Each field controls a specific aspect of compilation, from AST printing to backtrace behavior.
Key fields include:
optimization_level: Sets theOptLevelenum (0or1)print_ir: Configures IR output (initial, final, modified)print_asm: Controls assembly output stagesinclude_tests: Determines whether test functions are compiledterse: Minimizes warning and error output
Default Debug and Release Profiles
Sway provides two built-in profiles that serve as the baseline for all builds.
Debug Profile (No Optimizations)
The debug profile defaults to optimization_level = 0 (mapped to OptLevel::Opt0 in sway-core/src/build_config.rs), which skips all IR optimization passes for faster compilation. As implemented in forc-pkg/src/manifest/build_profile.rs at line 71, this profile prioritizes build speed and debugging information over performance.
Default debug configuration:
[build-profile.debug]
optimization_level = 0
print_asm = { virtual = false, allocated = false, final = true }
print_ir = { initial = false, final = true, modified = false, passes = [] }
terse = false
backtrace = "all_except_never"
Release Profile (Full Optimizations)
The release profile sets optimization_level = 1 (mapped to OptLevel::Opt1), enabling the full suite of IR optimization passes including dead-code elimination and SROA. This is defined at line 95 of forc-pkg/src/manifest/build_profile.rs.
Default release configuration:
[build-profile.release]
optimization_level = 1
print_asm = { virtual = true, allocated = false, final = true }
print_ir = { initial = true, final = false, modified = true, passes = ["dce", "sroa"] }
terse = true
backtrace = "only_always"
Creating Custom Build Profiles
You can define additional profiles under [build-profile.<custom_name>] in Forc.toml. Custom profiles inherit unspecified fields from the default debug profile, as handled by the merge logic in forc-pkg/src/manifest/mod.rs around line 820.
Example custom profile for optimized testing:
[build-profile.fast-test]
optimization_level = 1
include_tests = true
terse = true
print_ir = { final = true, modified = true, passes = [] }
To use a custom profile, run:
forc build --build-profile fast-test
Understanding Optimization Levels
The optimization_level field maps directly to the OptLevel enum defined in sway-core/src/build_config.rs (lines 48-53):
pub enum OptLevel {
#[default] Opt0 = 0, // No IR passes
Opt1 = 1, // Run all optimization passes
}
During compilation in sway-core/src/lib.rs (lines 469-479), the compiler checks this enum to determine whether to skip optimizations or run the full PassManager::run_all_passes routine.
- Opt0 (
optimization_level = 0): IR passes straight to code generation. Use this for faster builds during development. - Opt1 (
optimization_level = 1): Runs all optimization passes, producing smaller and more efficient bytecode for production deployment.
Overriding Profiles via CLI
CLI flags take precedence over Forc.toml settings, allowing temporary adjustments without editing the manifest.
Key flags:
--release: Selects thereleaseprofile (equivalent tooptimization_level = 1)--build-profile <name>: Uses a specific custom profile--opt-level <0|1>: Directly overrides the optimization level--asm <virtual|allocated|final|all>: Overridesprint_asmsettings--ir <initial|final|modified>: Overridesprint_irsettings
For example, to build with release settings but disable optimizations temporarily:
forc build --release --opt-level 0
Practical Configuration Example
Here's a complete Forc.toml demonstrating multiple profiles:
[project]
name = "my_contract"
authors = ["Alice"]
license = "Apache-2.0"
entry = "main.sw"
[build-profile.debug]
optimization_level = 0
terse = false
[build-profile.release]
optimization_level = 1
terse = true
[build-profile.ci]
optimization_level = 1
include_tests = true
error_on_warnings = true
terse = true
Build commands:
# Standard debug build (Opt0)
forc build
# Optimized release build (Opt1)
forc build --release
# CI-optimized build with tests
forc build --build-profile ci
# Quick optimization test without editing files
forc build --opt-level 1 --ir final
Summary
- Build profiles in Sway are defined as
[build-profile.<name>]tables inForc.tomland deserialized intoBuildProfilestructs inforc-pkg/src/manifest/build_profile.rs. - The
optimization_levelfield accepts0(Opt0, no IR passes) or1(Opt1, full optimizations), mapping to theOptLevelenum insway-core/src/build_config.rs. - Default
debugandreleaseprofiles are automatically injected if missing, withdebugdefaulting to level 0 andreleaseto level 1. - Custom profiles inherit missing fields from the base
debugprofile, allowing partial overrides. - CLI flags like
--release,--opt-level, and--build-profileoverride manifest settings for temporary configuration changes.
Frequently Asked Questions
What is the difference between Opt0 and Opt1 in Sway?
Opt0 (optimization_level = 0) skips all IR optimization passes, resulting in faster compilation times but larger bytecode. Opt1 (optimization_level = 1) runs the full optimization suite including dead-code elimination and SROA, producing smaller, more efficient bytecode suitable for production. These correspond to the OptLevel::Opt0 and OptLevel::Opt1 variants in sway-core/src/build_config.rs.
How do I create a custom build profile in Sway?
Add a [build-profile.<name>] table to your Forc.toml file and specify only the fields you want to override. Unspecified fields inherit values from the default debug profile. For example, [build-profile.fast] with optimization_level = 1 and include_tests = true creates an optimized test build. Activate it with forc build --build-profile fast.
Can I override optimization levels from the command line?
Yes. Use the --opt-level <0|1> flag to temporarily override the optimization_level specified in your profile. You can also use --release to select the release profile (which sets level 1) or --build-profile <name> to select a custom profile. CLI flags always take precedence over Forc.toml settings.
Where are the default debug and release profiles defined?
The default values for debug and release profiles are hardcoded in forc-pkg/src/manifest/build_profile.rs, specifically in the BuildProfile::debug() method at line 71 and BuildProfile::release() at line 95. If these tables are missing from your Forc.toml, the compiler automatically injects them before processing, as ensured by the logic in forc-pkg/src/manifest/mod.rs around line 820.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →