# How to Use Compile-Time Constants and Configurable Values in Sway

> Learn to use compile-time constants and configurable values in Sway. Understand the difference between const and configurable to manage your smart contract settings effectively.

- Repository: [Fuel Labs/sway](https://github.com/FuelLabs/sway)
- Tags: how-to-guide
- Published: 2026-03-04

---

**Sway distinguishes between compile-time constants (`const`) baked permanently into bytecode and configurable values (`configurable`) that default to compile-time expressions but can be overridden during contract deployment.**

When building smart contracts with the FuelLabs/sway repository, efficient management of immutable values is essential for both gas optimization and deployment flexibility. Learning how to use compile-time constants and configurable values in Sway enables developers to hardcode protocol-level invariants while allowing deployment-specific parameters like administrator addresses or token metadata to be customized. This guide explores the internal implementation, from AST parsing in `sway-ast` to deployment encoding in `forc-util`.

## Understanding the Difference Between Constants and Configurables

Sway resolves both value types before execution, but they differ in mutability during the deployment phase:

| Feature | Compile-Time Constant | Configurable Value |
|---------|---------------------|-------------------|
| **Syntax** | `const NAME: TYPE = EXPR;` | `configurable { const NAME: TYPE = EXPR; }` |
| **Evaluation** | During compilation by the constant evaluator | Initial value evaluated at compile time, but overridable at deployment |
| **Storage** | Inlined into generated bytecode | Stored in contract's configurable metadata section |
| **Changeable** | Never | Only during deployment via transaction parameters |

The AST representation for constants lives in [`sway-ast/src/item/item_const.rs`](https://github.com/FuelLabs/sway/blob/main/sway-ast/src/item/item_const.rs), while configurables are parsed into `ItemConfigurable` nodes defined in [`sway-ast/src/item/item_configurable.rs`](https://github.com/FuelLabs/sway/blob/main/sway-ast/src/item/item_configurable.rs).

## Declaring Compile-Time Constants

Use the `const` keyword for values that must remain identical across all deployments, such as mathematical constants or protocol identifiers. The compiler evaluates these expressions using the constant-evaluation engine in [`sway-core/src/type_system/engine.rs`](https://github.com/FuelLabs/sway/blob/main/sway-core/src/type_system/engine.rs), inlining the literal values directly into the bytecode.

```sway
library math_constants;

pub const PI_NUMERATOR: u64 = 314159265;
pub const MAX_DECIMALS: u8 = 18;

// Usage in contract
contract Calculator {
    fn calculate() -> u64 {
        PI_NUMERATOR / MAX_DECIMALS
    }
}

```

Because the compiler resolves these at build time, referencing a `const` incurs zero runtime overhead—the value is effectively hardcoded into the instruction stream.

## Using Configurable Values for Deployment Flexibility

The `configurable` block allows you to define defaults that deployers can override. Each declaration inside the block is a standard `const` statement processed by the same constant evaluator, but the values are serialized into the contract's configurable section rather than inlined.

```sway
contract Token {
    configurable {
        const OWNER: Address = #0;
        const NAME: str[32] = "DefaultToken";
        const SYMBOL: str[8] = "DTK";
        const INITIAL_SUPPLY: u64 = 1_000_000;
    }

    storage {
        total_supply: u64 = INITIAL_SUPPLY,
    }

    #[storage(read)]
    fn get_config() -> (str[32], str[8]) {
        (NAME, SYMBOL)
    }
}

```

The `encode_configurable` function in `sway-lib-std/src/codec.sw` handles the serialization of these values for the VM.

## Deploying with Custom Configurables

Override configurable values using the `forc deploy` command with the `--configurables` flag. The deployment utilities in [`forc-util/src/tx_utils.rs`](https://github.com/FuelLabs/sway/blob/main/forc-util/src/tx_utils.rs) handle parsing and encoding these overrides into the transaction.

```bash
forc build

forc deploy --configurables "OWNER=0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890,INITIAL_SUPPLY=500_000"

```

If you omit a configurable, the compiler uses the default expression defined in the source code. The VM loads these values once during instantiation and binds them to the contract's symbol table as immutable variables.

## Internal Implementation Details

Both `const` declarations and configurable initial values pass through the constant-evaluation engine in [`sway-core/src/type_system/engine.rs`](https://github.com/FuelLabs/sway/blob/main/sway-core/src/type_system/engine.rs). This engine requires expressions to be fully resolvable at compile time—attempting to use runtime data results in a compilation error.

For configurables, the compiler generates metadata that the Fuel VM reads during contract instantiation. The encoding process utilizes `encode_configurable` from the standard library (`sway-lib-std/src/codec.sw`) to produce the raw slice stored in the configurable section.

## Best Practices for Choosing Between Constants and Configurables

- **Use `const`** for universal invariants like mathematical constants, fixed protocol addresses, or magic numbers that should never vary between deployments.

- **Use `configurable`** for deployment-specific parameters such as administrator addresses, token metadata, initial supply caps, or feature flags that must remain immutable after deployment but differ across instances.

The `examples/configurable_constants/src/main.sw` file in the repository provides a minimal working example demonstrating both patterns.

## Summary

- Compile-time constants (`const`) are inlined into bytecode and immutable forever, parsed by [`sway-ast/src/item/item_const.rs`](https://github.com/FuelLabs/sway/blob/main/sway-ast/src/item/item_const.rs).
- Configurable values (`configurable`) default to compile-time expressions but can be overridden during deployment using `forc deploy --configurables`.
- Both value types are evaluated by the constant-evaluation engine in [`sway-core/src/type_system/engine.rs`](https://github.com/FuelLabs/sway/blob/main/sway-core/src/type_system/engine.rs) before deployment.
- Configurables are encoded via `encode_configurable` in `sway-lib-std/src/codec.sw` and stored in the contract's configurable metadata section.
- Choose `const` for universal constants and `configurable` for deployment-specific settings that must remain immutable after instantiation.

## Frequently Asked Questions

### Can I change a configurable value after deploying a contract?

No. Configurable values can only be set during the initial deployment transaction. Once the contract is instantiated on-chain, the values become immutable and are loaded into the VM's symbol table as constant variables.

### What happens if I deploy without specifying all configurables?

The compiler uses the default values defined in the `configurable` block's const expressions. These defaults are evaluated at compile time by the constant evaluator, so the contract always has valid values regardless of deployment overrides.

### Can I use runtime data to calculate a configurable value?

No. Both `const` declarations and configurable initial values must be compile-time evaluable. The constant-evaluation engine in [`sway-core/src/type_system/engine.rs`](https://github.com/FuelLabs/sway/blob/main/sway-core/src/type_system/engine.rs) rejects expressions that depend on runtime inputs, storage, or external calls.

### How do configurable values differ from storage variables?

Configurable values are set once at deployment and stored in the contract's metadata section, while storage variables are mutable state that can be updated by contract methods during execution. Configurables are more gas-efficient for immutable configuration but cannot be changed after deployment, unlike storage variables.