# Sway — User Guide

Sway is a domain-specific programming language for smart contract development on the Fuel blockchain. Inspired by Rust's syntax and safety guarantees, Sway compiles to FuelVM bytecode and is paired with `forc` — the Fuel Orchestrator — a build tool and package manager analogous to Rust's `cargo`. Together, they form the complete developer experience for building contracts, scripts, predicates, and libraries on Fuel.

**Version:** 0.71.0 (commit `e12e611`)
**Toolchain:** forc with 16 built-in subcommands and 8 plugin binaries

---

## 1. Quick Start

Get from zero to a running Sway contract in under five minutes.

### Prerequisites

- A Unix-like terminal (Linux, macOS, or WSL2 on Windows)
- `git` installed and accessible from your shell
- Internet access for downloading the toolchain

### Install fuelup

`fuelup` is the official Fuel toolchain manager. It installs and manages `forc` and all associated tools.

```bash
curl https://install.fuel.network | sh
```

Follow the on-screen instructions. Reload your shell or run:

```bash
source ~/.bashrc   # or ~/.zshrc, ~/.profile — whichever your shell uses
```

Verify the install:

```bash
fuelup --version
forc --version
```

### Create your first project

```bash
forc new hello-fuel
cd hello-fuel
```

This generates:

```
hello-fuel/
  Forc.toml       # Manifest (like Cargo.toml)
  src/
    main.sw       # Entry point — a contract by default
```

The generated `src/main.sw` looks like:

```sway
contract;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}
```

### Build and inspect

```bash
forc build
```

Output lands in `out/`:

```
out/
  debug/
    hello-fuel.bin        # Contract bytecode
    hello-fuel-abi.json   # ABI for external tooling
```

> [!TIP]
> Run `forc check` instead of `forc build` when you only want to type-check your code. It skips code generation and runs significantly faster — ideal for rapid iteration during development.

### Run tests

```bash
forc test
```

Tests are written inline with `#[test]` attributes directly in your Sway source files. No separate test directory is required.

### Next steps

- Learn the four [program types](#41-program-types)
- Explore every [forc subcommand](#4-core-usage)
- See the full [CLI reference tables](#44-forc-cli-reference)

---

## 2. Installation

### 2.1 Installing via fuelup (Recommended)

`fuelup` manages Fuel toolchain versions, analogous to `rustup`. It is the recommended installation path for all platforms.

```bash
curl https://install.fuel.network | sh
```

After installation, `fuelup` adds itself and the toolchain binaries to `~/.fuelup/bin`. Make sure this directory is on your `PATH`.

```bash
export PATH="$HOME/.fuelup/bin:$PATH"
```

Add that line to your shell's RC file (`~/.bashrc`, `~/.zshrc`, etc.) to make it permanent.

#### Install a specific toolchain

```bash
fuelup toolchain install latest
fuelup toolchain install nightly
fuelup default latest
```

#### Switch between toolchains

```bash
fuelup default nightly
fuelup default latest
```

#### Update the toolchain

```bash
fuelup update
```

> [!IMPORTANT]
> Always use `fuelup update` rather than re-running the install curl script. Re-running the installer may reset your default toolchain selection. `fuelup update` intelligently upgrades only what has changed.

### 2.2 Verify installation

After install, confirm all core tools are present:

```bash
forc --version
forc-fmt --version
forc-lsp --version
forc-doc --version
```

Check installed plugins:

```bash
forc plugins
```

Expected output lists all installed plugin binaries.

### 2.3 Shell completions

Generate completions for your shell:

```bash
# Bash
forc completions --shell bash >> ~/.bash_completion

# Zsh
forc completions --shell zsh > ~/.zfunc/_forc

# Fish
forc completions --shell fish > ~/.config/fish/completions/forc.fish

# PowerShell
forc completions --shell powershell >> $PROFILE

# Elvish
forc completions --shell elvish >> ~/.elvish/rc.elv

# Fig (macOS autocomplete)
forc completions --shell fig
```

> [!NOTE]
> For zsh completions, ensure your `fpath` includes `~/.zfunc` and that `compinit` runs in your `.zshrc`. Add `fpath=(~/.zfunc $fpath)` before the `autoload -Uz compinit && compinit` line.

After generating completions, restart your shell or source the relevant file.

### 2.4 Platform-specific notes

#### Linux

Standard installation works on Ubuntu 20.04+, Fedora 36+, and other glibc-based distributions. The `musl` target is not officially supported.

#### macOS

Works on macOS 12+ (Monterey and later). Apple Silicon (M1/M2/M3) is fully supported via native ARM builds.

#### Windows (WSL2)

Native Windows is not supported. Use WSL2 with Ubuntu 22.04 or later. Install `fuelup` inside the WSL2 environment, not in the Windows host.

> [!WARNING]
> Do not attempt to run `forc` or `fuelup` from a Windows Command Prompt or PowerShell directly. The Fuel toolchain requires a Unix-compatible environment. WSL2 is the supported Windows path.

### 2.5 Building from source

For contributors or when a specific unreleased commit is required:

```bash
git clone https://github.com/FuelLabs/sway.git
cd sway
cargo build --release -p forc
```

The binary lands at `target/release/forc`. Add it to your `PATH` or use it directly.

Prerequisites for building from source:
- Rust stable (1.76 or later)
- `cargo` (bundled with Rust)
- Standard C build tools (`gcc`, `make`, `pkg-config`)

---

## 3. Configuration

### 3.1 The Forc.toml manifest

Every Sway project is described by a `Forc.toml` file at the project root. This is the single source of truth for package metadata, dependencies, build profiles, and workspace membership.

#### Minimal contract manifest

```toml
[project]
name = "my-contract"
version = "0.0.1"
entry = "main.sw"
license = "Apache-2.0"

[dependencies]
```

#### Full manifest reference

```toml
[project]
name = "my-contract"          # Package name (required)
version = "0.0.1"             # Semver version (required)
entry = "main.sw"             # Entry source file (default: main.sw or lib.sw)
license = "Apache-2.0"        # SPDX license identifier
authors = ["Alice <[email removed]>"]
description = "A sample Sway contract"
repository = "https://github.com/example/my-contract"
homepage = "https://example.com"
keywords = ["fuel", "defi"]
categories = ["finance"]

[dependencies]
# Registry dependencies
std = { version = "0.71.0" }

# Git dependencies
my-lib = { git = "https://github.com/example/my-lib", branch = "main" }

# Tag-pinned git dependency
other-lib = { git = "https://github.com/example/other-lib", tag = "v0.1.0" }

# Specific commit pinned
pinned-lib = { git = "https://github.com/example/pinned-lib", rev = "abc1234" }

# Local path dependency
local-utils = { path = "../local-utils" }

[build-profile.debug]
# Debug profile is the default. Optimizations off.

[build-profile.release]
# Release profile: run with `forc build --release`
```

### 3.2 Workspace manifest

A workspace groups multiple Sway packages under one root. Create a `Forc.toml` at the workspace root containing only a `[workspace]` section:

```toml
[workspace]
members = [
    "contracts/token",
    "contracts/exchange",
    "libraries/shared-types",
    "scripts/deploy-helper",
]
```

Initialize a workspace project with:

```bash
forc new my-workspace --workspace
```

Then add members manually by creating subdirectories with their own `Forc.toml` manifests and listing them in `members`.

> [!NOTE]
> Workspace-level `forc build`, `forc test`, and `forc check` operate on all members. Use `--path` to target a specific member: `forc build --path contracts/token`.

### 3.3 Build profiles

Two profiles exist: `debug` (default) and `release`.

```bash
forc build           # debug profile
forc build --release # release profile
```

Custom profiles can be defined in `Forc.toml` under `[build-profile.<name>]`.

### 3.4 Experimental features

Sway has a feature flag system for opt-in or opt-out behaviors. Features have a defined precedence order (highest wins):

1. **Forc.toml manifest declaration** (highest precedence)
2. **CLI `--no-experimental <feature>`**
3. **CLI `--experimental <feature>`**
4. **`FORC_NO_EXPERIMENTAL` environment variable**
5. **`FORC_EXPERIMENTAL` environment variable** (lowest precedence)

#### Currently available features

| Feature | Default | Description |
|---|---|---|
| `new_encoding` | Enabled | New ABI encoding scheme |
| `references` | Enabled | Reference types in Sway |
| `new_hashing` | Enabled | Updated hashing semantics |
| `str_array_no_padding` | Disabled | String arrays without padding |
| `dynamic_storage` | Disabled | Dynamic storage capabilities |

#### Enable/disable via CLI

```bash
# Enable a disabled-by-default feature
forc build --experimental str_array_no_padding

# Disable an enabled-by-default feature
forc build --no-experimental new_encoding
```

#### Enable/disable via environment variable

```bash
# Enable via env (comma-separated list)
FORC_EXPERIMENTAL=str_array_no_padding forc build

# Disable via env
FORC_NO_EXPERIMENTAL=new_encoding forc build
```

#### Enable/disable in Forc.toml

```toml
[project]
name = "my-contract"
version = "0.0.1"
experimental = ["str_array_no_padding"]
no-experimental = ["new_encoding"]
```

### 3.5 Environment variables

All recognized environment variables for the Fuel toolchain:

| Variable | Purpose |
|---|---|
| `FORC_EXPERIMENTAL` | Comma-separated list of experimental features to enable |
| `FORC_NO_EXPERIMENTAL` | Comma-separated list of experimental features to disable |
| `FORC_PUB_TOKEN` | Authentication token for `forc publish` |
| `FORC_IMPLICIT_STD_PATH` | Override the path to the bundled `std` library |
| `FORC_IMPLICIT_STD_GIT` | Override the git URL used to fetch `std` |
| `FORC_IMPLICIT_STD_GIT_TAG` | Override the git tag for the `std` fetch |
| `FORC_IMPLICIT_STD_GIT_BRANCH` | Override the git branch for the `std` fetch |

> [!NOTE]
> The `FORC_IMPLICIT_STD_*` variables are primarily useful for toolchain developers and CI pipelines that need to test against a custom `std` build without modifying `Forc.toml`. Most users should never need them.

---

## 4. Core Usage

### 4.1 Program types

Every Sway source file must declare its program type as the very first statement. Sway supports four types:

#### contract

The most common type. Contracts are stateful programs deployed on-chain and called via transactions. They can hold storage, implement ABIs, and be called by other contracts or externally.

```sway
contract;

storage {
    balance: u64 = 0,
}

abi SimpleWallet {
    #[storage(read, write)]
    fn deposit();

    #[storage(read)]
    fn get_balance() -> u64;
}

impl SimpleWallet for Contract {
    #[storage(read, write)]
    fn deposit() {
        let amount = msg_amount();
        storage.balance.write(storage.balance.read() + amount);
    }

    #[storage(read)]
    fn get_balance() -> u64 {
        storage.balance.read()
    }
}
```

Build output: `.bin` bytecode + `-abi.json` ABI descriptor.

#### script

Scripts are single-execution programs that run in a transaction and can call contracts. They do not have persistent storage and cannot be called by other contracts. They are the equivalent of a "runner" or "orchestrator" in a transaction.

```sway
script;

fn main() -> bool {
    // Call contracts, perform computations, return a result
    true
}
```

Build output: `.bin` bytecode only.

#### predicate

Predicates are pure boolean programs used as spending conditions for UTXOs. They must return `true` for a transaction to consume the associated UTXO. Predicates have no storage and no side effects — they are deterministic.

```sway
predicate;

fn main() -> bool {
    // Inspect transaction fields and return true/false
    let sender = std::tx::tx_witness_data::<b256>(0);
    sender == 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
}
```

Build output: `.bin` bytecode only. Use `forc predicate-root` to compute the predicate root hash.

#### library

Libraries are reusable code modules. They do not have an entry point — they export functions, types, constants, and traits for use by other packages.

```sway
library;

pub fn add(a: u64, b: u64) -> u64 {
    a + b
}

pub struct Point {
    pub x: u64,
    pub y: u64,
}
```

Entry point: `src/lib.sw` (not `src/main.sw`).
Build output: `-abi.json` ABI descriptor (no `.bin`).

### 4.2 Project initialization

#### forc new

Create a new project directory and initialize it:

```bash
forc new my-project                  # contract (default)
forc new my-script --script
forc new my-predicate --predicate
forc new my-lib --library
forc new my-workspace --workspace
```

The `--name` flag overrides the inferred package name (useful when the directory name is not a valid package identifier):

```bash
forc new my-project-dir --name my_project
```

#### forc init

Initialize a Sway project in the current directory (or a specified existing directory). Useful when you already have a directory and want to add Sway tooling:

```bash
mkdir existing-dir && cd existing-dir
forc init                            # contract in current dir
forc init --script
forc init --predicate
forc init --library
forc init --path /absolute/path/to/dir
```

#### forc template

Create a new project from a git-hosted template:

```bash
forc template --url https://github.com/FuelLabs/sway-applications \
              --template-name counter \
              my-counter-project
```

This clones the template repository, extracts the named template, and wires it up as a new project at `my-counter-project/`.

### 4.3 Building

#### Basic build

```bash
forc build
```

Compiles the project in the current directory using the debug profile. Output goes to `out/debug/`.

#### Release build

```bash
forc build --release
```

Uses the release build profile. Output goes to `out/release/`.

#### Build a specific project

```bash
forc build --path /path/to/project
```

#### Offline build (use cached dependencies)

```bash
forc build --offline
```

Uses only locally cached dependencies. Fails if a dependency is not cached.

#### Locked build (enforce Forc.lock)

```bash
forc build --locked
```

Requires `Forc.lock` to already exist and be up-to-date. Fails rather than updating the lock file. Use this in CI to prevent unexpected dependency changes.

#### Terse output

```bash
forc build --terse
```

Suppresses informational output, showing only warnings and errors.

#### Build for EVM target

```bash
forc build --build-target evm
```

Compile targeting the EVM instead of FuelVM. The default is `fuel`.

#### Custom output directory

```bash
forc build --output-directory /tmp/my-build
```

#### Build with tests compiled in

```bash
forc build --tests
```

Compiles test functions into the binary. Required before running `forc test`.

#### Build and print AST

```bash
forc build --print-ast
```

Dumps the parsed abstract syntax tree to stdout after parsing.

#### Build and print IR

```bash
forc build --print-ir initial
forc build --print-ir final
forc build --print-ir passes
```

Dumps Sway IR at the specified stage. `initial` = before optimization, `final` = after, `passes` = after each pass.

#### Build and print ASM

```bash
forc build --print-asm virtual
forc build --print-asm allocated
forc build --print-asm final
```

Dumps assembly at different stages of code generation.

#### Print bytecode as hex

```bash
forc build --print-bytecode
```

#### Minify ABI output

```bash
forc build --minify-json-abi
forc build --minify-json-storage-slots
```

Removes whitespace from the output JSON files.

#### Treat warnings as errors

```bash
forc build --error-on-warnings
```

Fails the build if any warnings are emitted. Useful for CI and pre-commit hooks.

#### Performance timing

```bash
forc build --time-phases
```

Prints timing data for each compilation phase (parsing, type-checking, IR generation, codegen, etc.).

```bash
forc build --metrics-outfile metrics.json
```

Writes timing metrics to a JSON file.

#### Reverse error ordering

```bash
forc build --reverse-order
```

Emits errors in reverse order (last error first). Occasionally useful when the root cause is buried under cascading errors.

### 4.4 forc CLI reference

#### Global flags (apply to all subcommands)

| Flag | Short | Description |
|---|---|---|
| `--verbose` | `-v` | Enable verbose output |
| `--silent` | `-s` | Suppress all output except errors |
| `--log-level <LEVEL>` | `-L` | Set log level (error, warn, info, debug, trace) |
| `--help` | `-h` | Show help for the current subcommand |
| `--version` | `-V` | Show version and exit |

#### forc build flags

| Flag | Description |
|---|---|
| `--path <PATH>` | Path to project (default: current dir) |
| `--offline` | Use only cached dependencies |
| `--locked` | Require up-to-date Forc.lock, don't update |
| `--terse` | Minimal output (warnings + errors only) |
| `--release` | Use release build profile |
| `--tests` | Include test functions in compilation |
| `--build-target <TARGET>` | `fuel` (default) or `evm` |
| `--output-directory <DIR>` | Override output directory |
| `--print-ast` | Dump AST after parsing |
| `--print-asm <STAGE>` | Dump ASM (`virtual`, `allocated`, `final`) |
| `--print-ir <STAGE>` | Dump IR (`initial`, `final`, `passes`) |
| `--print-bytecode` | Print bytecode as hex |
| `--minify-json-abi` | Minify ABI JSON output |
| `--minify-json-storage-slots` | Minify storage slots JSON output |
| `--build-profile <NAME>` | Use a named build profile from Forc.toml |
| `--error-on-warnings` | Fail the build on any warning |
| `--experimental <FEATURE>` | Enable an experimental feature |
| `--no-experimental <FEATURE>` | Disable an experimental feature |
| `--time-phases` | Print timing for each compilation phase |
| `--metrics-outfile <FILE>` | Write metrics JSON to file |
| `--reverse-order` | Emit errors/warnings in reverse order |

#### forc new / forc init flags

| Flag | Description |
|---|---|
| `--contract` | Create a contract project (default for `new`/`init`) |
| `--script` | Create a script project |
| `--predicate` | Create a predicate project |
| `--library` | Create a library project |
| `--workspace` | Create a workspace |
| `--name <NAME>` | Override the package name |
| `--path <PATH>` | Target directory (for `init`) |

#### forc test flags

| Flag | Short | Description |
|---|---|---|
| `--path <PATH>` | | Path to the project |
| `--offline` | | Use cached dependencies only |
| `--locked` | | Require locked dependencies |
| `--terse` | | Minimal output |
| `--release` | | Test in release mode |
| `--filter <FILTER>` | | Run only tests matching the filter string |
| `--verbose` | `-v` | Verbose test output |
| `--logs` | | Print logs emitted during tests |
| `--experimental <FEATURE>` | | Enable experimental feature |
| `--no-experimental <FEATURE>` | | Disable experimental feature |

#### forc check flags

| Flag | Description |
|---|---|
| `--path <PATH>` | Path to project |
| `--offline` | Use cached dependencies |
| `--locked` | Require locked dependencies |
| `--experimental <FEATURE>` | Enable experimental feature |
| `--no-experimental <FEATURE>` | Disable experimental feature |

#### forc add flags

| Flag | Description |
|---|---|
| `--version <VERSION>` | Version constraint to add |
| `--git <URL>` | Git repository URL |
| `--branch <BRANCH>` | Git branch to use |
| `--tag <TAG>` | Git tag to use |
| `--rev <REV>` | Git commit hash to pin |
| `--path <PATH>` | Local path to dependency |

#### forc completions flags

| Flag | Short | Description |
|---|---|---|
| `--shell <SHELL>` | `-s` | Shell: `bash`, `zsh`, `fish`, `powershell`, `elvish`, `fig` |

#### forc plugins flags

| Flag | Description |
|---|---|
| `--path <PATH>` | Look for plugins in this directory instead of PATH |

#### All 16 built-in subcommands at a glance

| Subcommand | Alias | Description |
|---|---|---|
| `add` | | Add a dependency to Forc.toml |
| `addr2line` | | Resolve opcode address to source location |
| `build` | `b` | Compile the project |
| `check` | | Type-check without codegen |
| `clean` | | Remove the `out/` directory |
| `completions` | | Generate shell completions |
| `contract-id` | | Compute the contract ID |
| `init` | | Initialize project in current/specified dir |
| `new` | | Create new project at path |
| `parse-bytecode` | | Decode a .bin file into readable opcodes |
| `plugins` | | List installed forc plugins |
| `predicate-root` | | Compute predicate root hash |
| `remove` | | Remove a dependency from Forc.toml |
| `template` | | Create project from a git template |
| `test` | `t` | Run inline `#[test]` functions |
| `update` | | Update dependencies |

### 4.5 Type-checking without building

```bash
forc check
```

Performs full type-checking, borrow checking, and semantic analysis without generating any bytecode or ABI files. This is significantly faster than `forc build` and is the recommended command for rapid development feedback.

```bash
forc check --path /path/to/project
forc check --locked
```

### 4.6 Cleaning build artifacts

```bash
forc clean
```

Removes the `out/` directory for the current project. Equivalent to `rm -rf out/`.

```bash
forc clean --path /path/to/project
```

### 4.7 Dependency management

#### forc add

Add a dependency to `Forc.toml`:

```bash
# Add from the Fuel registry by name
forc add my-library

# Add a specific version
forc add my-library --version 0.2.0

# Add from a git repository
forc add my-library --git https://github.com/example/my-library

# Add from a git repo at a specific branch
forc add my-library --git https://github.com/example/my-library --branch dev

# Add from a local path
forc add my-library --path ../my-library
```

This writes the dependency entry into `Forc.toml` automatically. You do not need to manually edit the manifest for most cases.

#### forc remove

Remove a dependency from `Forc.toml`:

```bash
forc remove my-library
```

This removes the entry from `Forc.toml` and updates `Forc.lock`.

#### forc update

Update dependencies to their latest compatible versions:

```bash
forc update                   # Update all dependencies
forc update my-library        # Update a specific dependency
```

After running `forc update`, the `Forc.lock` file is regenerated. Commit this file to lock your build for reproducibility.

> [!TIP]
> Commit `Forc.lock` to version control for binary applications (contracts, scripts, predicates). For libraries, it is conventional to gitignore `Forc.lock` so downstream users resolve their own compatible versions.

### 4.8 Contract and predicate utilities

#### forc contract-id

Determine the contract ID (address) of a compiled contract without deploying:

```bash
forc contract-id
forc contract-id --path /path/to/contract
forc contract-id --release
```

The contract ID is a deterministic hash of the contract's bytecode. Knowing it in advance is useful for:
- Pre-computing addresses for cross-contract calls
- Verifying that a deployed contract matches expected bytecode
- Generating configuration for other contracts that reference this one

#### forc predicate-root

Compute the predicate root hash of a compiled predicate:

```bash
forc predicate-root
forc predicate-root --path /path/to/predicate
```

The predicate root is the hash used as the "address" of a predicate UTXO. It must match what the transaction expects.

### 4.9 Debugging and analysis

#### forc parse-bytecode

Parse a compiled `.bin` file and display it in a human-readable format:

```bash
forc parse-bytecode out/debug/my-contract.bin
```

Output shows decoded opcodes with operands. Useful for low-level inspection and verifying codegen output.

#### forc addr2line

Resolve a FuelVM opcode address back to its source location:

```bash
forc addr2line --contract-id 0xabc123... --opcode-index 42
```

Requires the binary and debug info to be available. Useful when a transaction fails at a specific opcode and you need to trace it back to source.

### 4.10 Publishing packages

#### forc publish

Publish a package to the Fuel registry:

```bash
FORC_PUB_TOKEN=your_token forc publish
```

Or:

```bash
forc publish --token your_token
```

Before publishing:
1. Ensure `Forc.toml` has `name`, `version`, `license`, and `description` set.
2. Your package must be compilable without errors.
3. You must have a valid registry account and token.

> [!IMPORTANT]
> Once a specific version is published, it cannot be overwritten or deleted. Increment your version number (`version` in `Forc.toml`) for each publish. Yanked versions remain accessible but are excluded from version resolution.

---

## 5. Common Tasks

### 5.1 Writing and running tests

Sway tests are inline `#[test]` functions. They live in the same source files as your code.

```sway
contract;

fn add(a: u64, b: u64) -> u64 {
    a + b
}

#[test]
fn test_add() {
    assert(add(2, 3) == 5);
}

#[test]
fn test_add_zero() {
    assert(add(0, 100) == 100);
}
```

Run all tests:

```bash
forc test
```

Run tests matching a filter:

```bash
forc test --filter test_add
```

Print logs emitted during tests:

```bash
forc test --logs
```

Run tests in verbose mode (shows each test name and result):

```bash
forc test --verbose
```

#### Test with should_revert

Use `#[test(should_revert)]` for tests that are expected to panic or revert:

```sway
#[test(should_revert)]
fn test_division_by_zero() {
    let _ = 10_u64 / 0_u64;
}
```

### 5.2 Formatting code

Use `forc-fmt` to automatically format your Sway source files:

```bash
# Format all .sw files in the current project
forc fmt

# Check formatting without modifying files (exit code 1 if changes needed)
forc fmt --check

# Format a specific file or directory
forc fmt src/main.sw
forc fmt src/
```

> [!TIP]
> Add `forc fmt --check` to your CI pipeline to enforce consistent formatting. The `--check` flag returns a non-zero exit code if any files would be changed, making it safe to use as a gate.

`forc-fmt` follows the official Sway style guide and is the canonical formatter — no configuration options are exposed. The style is intentionally opinionated.

### 5.3 Generating documentation

Use `forc-doc` to generate HTML documentation from doc comments (`///`) in your source:

```bash
# Generate docs for the current project
forc doc

# Generate and immediately open in browser
forc doc --open
```

Doc comments use triple slashes:

```sway
/// Calculates the sum of two unsigned 64-bit integers.
///
/// # Arguments
///
/// * `a` - The first operand.
/// * `b` - The second operand.
///
/// # Returns
///
/// The sum of `a` and `b`.
pub fn add(a: u64, b: u64) -> u64 {
    a + b
}
```

Generated HTML is written to `out/doc/`. Open `out/doc/index.html` in your browser.

### 5.4 Using the Language Server (LSP)

`forc-lsp` provides IDE integration: completions, hover info, go-to-definition, diagnostics, and rename.

Start the LSP server:

```bash
forc lsp
```

This is rarely called directly — your editor's Sway extension manages it automatically.

#### VS Code

Install the **Sway** extension from the VS Code Marketplace. It automatically discovers and launches `forc-lsp`. Diagnostics appear in real time as you type.

#### Neovim

Use `nvim-lspconfig` with the `sway` language server entry, pointing to `forc-lsp` as the command.

> [!NOTE]
> `forc-lsp` reads `Forc.toml` to understand your project structure. Always open VS Code (or your editor) at the project root — the directory containing `Forc.toml` — not a subdirectory, or LSP features will be degraded.

### 5.5 Deploying and running contracts

Deploy a contract to a local Fuel node or testnet using `forc-client`:

```bash
# Deploy to a local node (default: http://localhost:4000)
forc deploy

# Deploy to testnet
forc deploy --node-url https://testnet.fuel.network/v1/graphql

# Run a script
forc run --node-url https://testnet.fuel.network/v1/graphql
```

`forc-client` is a plugin (`forc-deploy` / `forc-run`) installed alongside the main toolchain via `fuelup`.

### 5.6 Using the debugger

`forc-debug` implements the Debug Adapter Protocol (DAP), allowing step-through debugging of Sway programs:

```bash
forc debug
```

Connect your editor (VS Code, etc.) to the DAP server for interactive debugging. Set breakpoints in `.sw` files and inspect VM state.

### 5.7 Migrating projects

When breaking language changes land in a new Sway version, `forc-migrate` helps automate updates:

```bash
forc migrate
```

This analyzes your project and applies automated fixes for known migration paths. Review changes before committing.

### 5.8 Working with ABI files

The ABI JSON file (`out/debug/{name}-abi.json`) is the interface descriptor for a contract. Downstream tools use it to encode/decode function calls and events.

Build and inspect the ABI:

```bash
forc build
cat out/debug/my-contract-abi.json
```

For compact ABI files (e.g., for on-chain storage or size-constrained contexts):

```bash
forc build --minify-json-abi
```

### 5.9 Multi-contract projects (workspaces)

```
my-workspace/
  Forc.toml                   # workspace manifest
  token-contract/
    Forc.toml
    src/main.sw
  exchange-contract/
    Forc.toml
    src/main.sw
  shared-lib/
    Forc.toml
    src/lib.sw
```

Workspace `Forc.toml`:

```toml
[workspace]
members = [
    "token-contract",
    "exchange-contract",
    "shared-lib",
]
```

Build all members:

```bash
cd my-workspace
forc build
```

Build a specific member:

```bash
forc build --path token-contract
```

Reference a workspace sibling as a dependency using a path dep:

```toml
# exchange-contract/Forc.toml
[dependencies]
shared-lib = { path = "../shared-lib" }
```

### 5.10 Cross-contract calls

Contracts can call other contracts via ABI casts. First, import the ABI:

```sway
contract;

// Declare the ABI of the target contract
abi Token {
    fn transfer(to: Address, amount: u64);
    fn balance_of(addr: Address) -> u64;
}

abi Exchange {
    fn swap(token_contract_id: ContractId, amount: u64) -> u64;
}

impl Exchange for Contract {
    fn swap(token_contract_id: ContractId, amount: u64) -> u64 {
        // Cast to ABI to make cross-contract call
        let token = abi(Token, token_contract_id.into());
        token.transfer(msg_sender().unwrap().as_address().unwrap(), amount);
        amount
    }
}
```

### 5.11 Writing libraries

Libraries live in `src/lib.sw`. Use `pub` to export items:

```sway
library;

pub mod math;
pub mod types;

pub use math::add;
pub use types::Point;
```

Sub-modules go in separate files (e.g., `src/math.sw`):

```sway
library;

pub fn add(a: u64, b: u64) -> u64 {
    a + b
}
```

Reference a library from a contract:

```toml
# Forc.toml
[dependencies]
my-lib = { path = "../my-lib" }
```

```sway
contract;
use my_lib::add;
```

> [!NOTE]
> Module names in Sway use underscores (`my_lib`) even if the package name in `Forc.toml` uses hyphens (`my-lib`). Hyphens are converted to underscores when resolving module identifiers.

### 5.12 Storage in contracts

Sway contracts declare all storage in a top-level `storage` block:

```sway
contract;

storage {
    owner: Address = Address::from(0x0000000000000000000000000000000000000000000000000000000000000000),
    balances: StorageMap<Address, u64> = StorageMap {},
    items: StorageVec<u64> = StorageVec {},
    counter: u64 = 0,
}
```

Read and write storage:

```sway
#[storage(read)]
fn get_counter() -> u64 {
    storage.counter.read()
}

#[storage(read, write)]
fn increment() {
    let current = storage.counter.read();
    storage.counter.write(current + 1);
}
```

Access a `StorageMap`:

```sway
#[storage(read, write)]
fn set_balance(addr: Address, amount: u64) {
    storage.balances.insert(addr, amount);
}

#[storage(read)]
fn get_balance(addr: Address) -> u64 {
    storage.balances.get(addr).try_read().unwrap_or(0)
}
```

> [!WARNING]
> Known issue: `StorageVec::insert()` does not work correctly with nested storage types (issue #6040). If you need nested storage (a `StorageVec` of structs that themselves contain storage-typed fields), use a `StorageMap<u64, T>` indexed manually as a workaround until this is resolved upstream.

### 5.13 Configuring CI with forc

A minimal CI workflow (GitHub Actions):

```yaml
name: Sway CI

on: [push, pull_request]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install fuelup
        run: curl https://install.fuel.network | sh -s -- --no-modify-path
        env:
          FUELUP_HOME: ~/.fuelup

      - name: Add fuelup to PATH
        run: echo "$HOME/.fuelup/bin" >> $GITHUB_PATH

      - name: Check formatting
        run: forc fmt --check

      - name: Type-check
        run: forc check --locked

      - name: Build
        run: forc build --locked --release --error-on-warnings

      - name: Test
        run: forc test --locked
```

Key flags for CI:
- `--locked` — ensures `Forc.lock` is respected and not silently updated
- `--error-on-warnings` — fails on any warning
- `forc fmt --check` — enforces formatting

### 5.14 Using forc-tx for transaction construction

`forc-tx` is a plugin for building raw Fuel transactions:

```bash
forc tx
```

This is an advanced tool primarily for protocol integrators who need to construct and inspect transaction structures without going through a higher-level SDK. For most application development, use the Fuel Rust SDK (`fuels`) instead.

### 5.15 Inspecting installed plugins

List all forc plugin binaries currently on your PATH:

```bash
forc plugins
```

Sample output:

```
forc-debug
forc-doc
forc-fmt
forc-lsp
forc-migrate
forc-publish
forc-tx
forc-client (provides forc-deploy, forc-run)
```

If an expected plugin is missing, verify it was installed via `fuelup` and that `~/.fuelup/bin` is on your PATH.

### 5.16 Working with the EVM build target

Sway includes experimental EVM compilation support:

```bash
forc build --build-target evm
```

This compiles your Sway program to EVM bytecode. The feature is experimental and not all Sway constructs are supported. The default and primary target remains `fuel`. Do not use EVM output for production unless you have verified full feature compatibility.

### 5.17 Understanding the output directory structure

After a build, `out/` contains:

```
out/
  debug/                          # or release/
    my-contract.bin               # FuelVM bytecode (contracts, scripts, predicates)
    my-contract-abi.json          # ABI descriptor (contracts, libraries)
    my-contract-storage_slots.json  # Storage slot declarations (contracts)
  doc/                            # Generated HTML docs (forc doc)
```

The `-storage_slots.json` file describes all storage variables and their slot keys. It is used by deployment tooling to initialize storage correctly.

---

## 6. Troubleshooting

### Error: `could not find Forc.toml in this directory or any of its parents`

**Cause:** You are running a forc command outside of a Sway project directory.

**Solution:** Navigate to your project root (where `Forc.toml` lives) before running forc commands, or use `--path`:

```bash
forc build --path /absolute/path/to/my-project
```

**Prevention:** Always verify your working directory with `ls Forc.toml` before running forc commands.

---

### Error: `Dependency cycle detected`

**Cause:** Package A depends on Package B, which directly or transitively depends back on Package A.

**Solution:** Refactor shared code into a third library that both A and B depend on, breaking the cycle.

**Prevention:** Design your library hierarchy as a DAG (directed acyclic graph). Libraries should only depend downward, never in circles.

---

### Error: `could not compile` with no further details

**Cause:** Often occurs when the project has never been built and `Forc.lock` is missing or stale.

**Solution:**

```bash
forc clean
forc build
```

If that fails, run with verbose output:

```bash
forc build -v
```

**Prevention:** Don't `.gitignore` `Forc.lock` for contracts and scripts.

---

### Error: `Compiler ICE` (Internal Compiler Error)

**Cause:** You have triggered an unhandled compiler code path — a bug. Active known ICEs include array const generics edge cases (issues #7603, #7604, #7602).

**Solution:** File an issue at https://github.com/FuelLabs/sway/issues with a minimal reproduction. In the meantime, simplify the problematic construct:
- Avoid combining type aliases with const generic arrays (#7604)
- Avoid self-indexing (`self[i]`) with const generics (#7602)
- Avoid invalid unification of arrays with const generics (#7603)

**Prevention:** Keep Sway toolchain updated. ICEs are fixed quickly once reported.

---

### Error: `could not find symbol` with const generic functions

**Cause:** Issue #7599. The compiler fails to resolve symbols in certain const generic function contexts.

**Solution:** As a workaround, avoid relying on const generic functions in complex symbol resolution chains. Refactor to pass concrete types where possible until the fix is merged.

---

### Error: `Type is not indexable` on const generic array reassignment

**Cause:** Issue #7600. Reassigning to a const generic array emits a misleading "Type is not indexable" error instead of a clear description of the actual issue.

**Solution:** Report the issue and avoid const generic arrays in reassignment positions as a workaround. Use a plain fixed-size array or a `Vec` in the interim.

---

### Error: confusing `out-of-bounds` message with const generic arrays

**Cause:** Issue #7605. Out-of-bounds error messages for const generic arrays are confusing or point to incorrect source locations.

**Solution:** Carefully verify array sizes match usage. Compile with `--print-ast` to inspect resolved types and confirm the sizes the compiler sees.

---

### Warning: `CEI pattern violation` appears inconsistently

**Cause:** Issue #7606. CEI (Checks-Effects-Interactions) pattern warnings are emitted nondeterministically — the same code may or may not warn across builds.

**Solution:** Follow CEI pattern discipline regardless of whether a warning appears:
1. All checks first
2. Storage writes (effects)
3. External calls (interactions) last

**Prevention:** Do not rely on CEI warnings to catch violations. Manually audit all sequences involving storage writes followed by external calls.

---

### Error: `lock file is out of date`

**Cause:** `Forc.lock` does not match `Forc.toml`. Happens when you modify `Forc.toml` manually or pull changes from git that include `Forc.toml` updates.

**Solution:**

```bash
forc update
```

Or, to update a specific dependency:

```bash
forc update std
```

**Prevention:** Always run `forc update` after pulling changes that modify `Forc.toml`.

---

### Error: `failed to download crate`

**Cause:** Network issue or the registry is temporarily unavailable.

**Solution:**

```bash
# Retry the build (transient failure)
forc build

# If repeatedly failing, use local cache
forc build --offline
```

**Prevention:** For production CI, pin dependencies to specific git tags and run with `--locked` to avoid live registry fetches during builds.

---

### Error: `unauthorized` from forc publish

**Cause:** The `FORC_PUB_TOKEN` environment variable is missing or invalid.

**Solution:**

```bash
export FORC_PUB_TOKEN=your_token_here
forc publish
```

Or pass it directly:

```bash
forc publish --token your_token_here
```

---

### Error: missing storage annotation

**Cause:** A function reads or writes storage without being annotated with `#[storage(read)]` or `#[storage(read, write)]`.

**Solution:** Add the appropriate storage annotation:

```sway
// Read-only
#[storage(read)]
fn get_value() -> u64 {
    storage.value.read()
}

// Read and write
#[storage(read, write)]
fn set_value(v: u64) {
    storage.value.write(v);
}
```

---

### Error: `cannot find type` for an imported type

**Cause:** The type is defined in a dependency but not imported with `use`.

**Solution:**

```sway
use std::address::Address;
use my_lib::types::MyStruct;
```

Or use the full path inline:

```sway
let addr: std::address::Address = ...;
```

---

### Error: `main function not found`

**Cause:** Your project is a script or predicate and the entry point is missing, or you have an incorrect program type declaration.

**Solution:**
- Scripts and predicates need `fn main()` in `src/main.sw`
- Contracts need an ABI + `impl ContractName for Contract { }` — no bare `main`
- Libraries use `src/lib.sw` with no `main`

---

### forc test panics or hangs indefinitely

**Cause:** Issue #7551. The compiler can run infinitely on specific test inputs due to pathological type inference loops.

**Solution:** Identify which test triggers the hang using `--filter` to binary-search:

```bash
forc test --filter test_suspect_fn
```

Simplify the triggering function and file an issue with the minimal reproduction.

---

### Error: confusing `__gtf` error with non-const tx_field_id

**Cause:** Issue #7564 (closed/fixed in current release). The error message when passing a non-const value to `tx_field_id` in `__gtf` was misleading.

**Solution:** Update your toolchain — this is fixed. The `tx_field_id` argument to `__gtf` must be a compile-time constant.

```bash
fuelup update
```

---

### LSP shows no completions or diagnostics

**Cause:** `forc-lsp` is not found on PATH, or the editor extension is misconfigured.

**Solution:**

```bash
which forc-lsp          # verify it's on PATH
forc lsp --version      # verify it runs
```

In VS Code, open the Output panel → select "Sway Language Server" to see LSP logs.

**Prevention:** Always install via `fuelup` — it manages all plugin binaries in a consistent location.

---

### Build succeeds but ABI JSON is missing

**Cause:** Only contracts and libraries produce ABI JSON. Scripts and predicates produce only `.bin` output.

**Solution:** Verify your program type declaration:

```sway
contract;   // → produces -abi.json
library;    // → produces -abi.json
script;     // → .bin only, no ABI
predicate;  // → .bin only, no ABI
```

---

### Error: `Forc.toml` parse error

**Cause:** Invalid TOML syntax or an unrecognized field in `Forc.toml`.

**Solution:** Validate your TOML with a linter (`taplo check Forc.toml`). Common mistakes:
- Missing quotes around string values
- Using `:` instead of `=` for assignments
- Typos in section headers (`[dependecies]` instead of `[dependencies]`)

---

### forc build exits with no error but output is in unexpected location

**Cause:** Running `forc build` inside a workspace root builds all members. Each member's output goes into its own `out/` subdirectory.

**Solution:** Check each member's `out/` directory:

```bash
ls token-contract/out/debug/
ls exchange-contract/out/debug/
```

Or build a specific member:

```bash
forc build --path token-contract
```

---

### Error: `storage access is not allowed in this context`

**Cause:** Attempting to read or write storage in an unannotated context, a pure function, or a non-contract program type.

**Solution:** Add the `#[storage(read)]` or `#[storage(read, write)]` annotation to the function. Ensure the file declares `contract;` at the top — storage is only available in contracts.

---

### forc fmt produces unexpected changes

**Cause:** Your editor may be running an older `forc-fmt` binary with different formatting rules than the project's expected version.

**Solution:**

```bash
forc fmt --version
fuelup update
```

**Prevention:** Keep `fuelup` updated. The formatter's output is tied to the toolchain version.

---

### Error: `unresolved import`

**Cause:** Attempting to `use` a module path that doesn't exist in the dependency tree.

**Solution:** Verify the dependency is in `Forc.toml`, run `forc update`, and confirm the module path by checking the library's `src/lib.sw` for `pub mod` declarations.

---

### Error: predicate root mismatch at runtime

**Cause:** The predicate binary was rebuilt after the UTXO was locked to an older predicate root hash, causing the hashes to differ.

**Solution:** Lock UTXOs to a specific, stable predicate build. Use `forc predicate-root` to confirm the hash before locking funds:

```bash
forc predicate-root --path my-predicate
```

Pin the compiled binary (not just the source) if the predicate manages real funds.

---

### Error: `cannot move value` or `use of moved value`

**Cause:** Sway has ownership semantics similar to Rust. Values can only be used once unless they implement the `Copy` trait.

**Solution:** Use references where the value should not be consumed, or derive `Copy` on your struct if it wraps only copy-able types:

```sway
// Pass by reference to avoid move (requires `references` feature)
fn inspect(val: &MyStruct) { ... }
```

---

### Error: `__smo` or `__log` intrinsic compilation issue

**Cause:** Issue #7572 (closed/fixed in current release). `__smo` and `__log` intrinsics were not correctly compiled in certain contexts.

**Solution:** Update your toolchain:

```bash
fuelup update
```

---

### Large contracts exceed gas limits during testing

**Cause:** Complex contracts with deeply nested loops or many storage accesses accumulate high gas costs during test execution.

**Solution:**
- Split large contracts into multiple cooperating contracts
- Move pure computation into scripts
- Profile the specific function using the Fuel Rust SDK's gas estimation utilities

---

### forc build is extremely slow

**Cause:** Large dependency tree or pathological type inference on complex generics.

**Solution:**

```bash
# Use check for incremental feedback (faster than full build)
forc check

# Profile compilation phases
forc build --time-phases

# Skip network operations if dependencies are cached
forc build --offline
```

**Prevention:** Keep the dependency tree shallow. Each additional dependency increases compilation time.

---

### Error: `StorageKey impl fails to resolve get() on StorageMap` in generic context

**Cause:** Issue #7559. Generic `StorageKey` implementations fail to resolve `get()` on `StorageMap` when used through generic type parameters.

**Solution:** Use concrete types rather than generic `StorageKey` parameters when working with `StorageMap`. File the specific reproduction with issue #7559 if you encounter a new variant.

---

### Error: `version conflict` between dependencies

**Cause:** Two dependencies require incompatible versions of a shared transitive dependency.

**Solution:** Check which packages are in conflict:

```bash
forc build -v 2>&1 | grep "version"
```

Try pinning the conflicting transitive dependency directly in your `Forc.toml`, or upgrade/downgrade one of your direct dependencies to a version that resolves the conflict.

---

### forc doc generates empty or incomplete documentation

**Cause:** Doc comments must use `///` (triple slash), not `//` or `/* */`.

**Solution:**

```sway
/// This is a doc comment and will appear in generated docs.
pub fn my_func() {}

// This is a regular comment and will NOT appear in docs.
fn internal_func() {}
```

---

### Error: `entry point not found in library`

**Cause:** A library project has `src/main.sw` instead of `src/lib.sw`.

**Solution:** Rename the entry file:

```bash
mv src/main.sw src/lib.sw
```

Update `Forc.toml` if it explicitly sets `entry = "main.sw"`:

```toml
[project]
entry = "lib.sw"
```

---

## 7. FAQ

**Q: What is Sway, and how is it different from Solidity?**

Sway is a statically-typed, compiled language for the Fuel blockchain, syntactically inspired by Rust. Unlike Solidity (EVM-based, dynamic dispatch, JavaScript-like syntax), Sway targets the FuelVM with an ownership model, pattern matching, algebraic types, and generics. Sway is not EVM-compatible by default, though an experimental `--build-target evm` flag exists.

---

**Q: What is forc?**

`forc` (Fuel Orchestrator) is the official build tool and package manager for Sway. It handles project creation, compilation, testing, dependency management, formatting, and more — analogous to Rust's `cargo`. It ships with 16 built-in subcommands and is extended by plugin binaries.

---

**Q: What are the four program types in Sway?**

`contract` (stateful, on-chain callable), `script` (one-shot transaction runner), `predicate` (boolean spending condition for UTXOs), and `library` (reusable code module). Every Sway source file declares its type as the very first statement.

---

**Q: What is the difference between `forc build` and `forc check`?**

`forc check` performs type-checking and semantic analysis without generating any output files. It is faster. `forc build` does everything `check` does, plus IR generation, optimization, and bytecode/ABI output. Use `check` for fast feedback during development, `build` when you need the actual artifacts.

---

**Q: Where does forc put compiled output?**

`out/debug/` for debug builds, `out/release/` for release builds. Override with `--output-directory`. Each build produces:
- A `.bin` file for contracts, scripts, and predicates
- A `-abi.json` file for contracts and libraries
- A `-storage_slots.json` file for contracts with storage

---

**Q: What is Forc.lock and should I commit it?**

`Forc.lock` is an auto-generated lockfile that records the exact resolved version of every dependency. Commit it for contracts, scripts, and predicates (binary outputs) to ensure reproducible builds. For library packages, it is conventional to gitignore it so consumers resolve their own compatible versions.

---

**Q: How do I pin a dependency to a specific git commit?**

In `Forc.toml`:

```toml
[dependencies]
my-lib = { git = "https://github.com/example/my-lib", rev = "abc1234" }
```

---

**Q: Can I use Rust crates in Sway?**

No. Sway is a separate language that compiles to FuelVM bytecode. It cannot import Rust crates. The Rust SDK (`fuels-rs`) is used on the caller side (scripts, deployment tools, integration tests) — not inside Sway programs themselves.

---

**Q: How do I write tests for a contract?**

Inline unit tests use `#[test]`:

```sway
#[test]
fn test_my_function() {
    assert(my_function() == expected_value);
}
```

For integration tests (deploying and calling a real contract with state), use the Fuel Rust SDK (`fuels`) in a Rust test harness.

---

**Q: What is `std` in the Sway dependency tree?**

`std` is the Sway standard library. It is implicitly added to most projects. It provides common types (`Address`, `ContractId`, `b256`), utilities, cryptographic functions, and storage primitives. Override the implicit std location with `FORC_IMPLICIT_STD_*` environment variables.

---

**Q: How do I enable experimental features?**

Via CLI:

```bash
forc build --experimental str_array_no_padding
```

Via environment:

```bash
FORC_EXPERIMENTAL=str_array_no_padding forc build
```

Via `Forc.toml`:

```toml
[project]
experimental = ["str_array_no_padding"]
```

---

**Q: What is a predicate root?**

The predicate root is the SHA-256 hash of the predicate's bytecode. It functions as the "address" that UTXOs are locked to. A transaction can spend such a UTXO only if it includes the matching predicate bytecode that hashes to the same root and evaluates to `true`. Compute it with `forc predicate-root`.

---

**Q: How do I find the contract ID before deploying?**

```bash
forc contract-id
```

The contract ID is deterministically derived from the bytecode. It will be the same every time you compile the same source at the same toolchain version.

---

**Q: How do I add IDE support?**

For VS Code: install the **Sway** extension from the marketplace. It uses `forc-lsp` for real-time diagnostics, completions, and hover docs. For Neovim/Helix: configure `forc-lsp` as a language server via `nvim-lspconfig` or your editor's equivalent LSP configuration.

---

**Q: Can contracts call other contracts?**

Yes. Use an ABI cast:

```sway
let other = abi(OtherAbi, other_contract_id.into());
let result = other.some_function(arg);
```

This is how DeFi protocols, token standards, and multi-contract systems are built on Fuel.

---

**Q: What is CEI order and why does it matter?**

CEI stands for Checks-Effects-Interactions — a security pattern for preventing reentrancy:
1. **Checks** — validate inputs, balances, permissions
2. **Effects** — write to storage
3. **Interactions** — call external contracts

Violating this order (writing to an external contract before updating state) opens reentrancy vulnerabilities. Follow CEI order regardless of whether the compiler warns about it (warning generation is nondeterministic per issue #7606).

---

**Q: How do I generate shell completions?**

```bash
forc completions --shell bash >> ~/.bash_completion
forc completions --shell zsh > ~/.zfunc/_forc
forc completions --shell fish > ~/.config/fish/completions/forc.fish
forc completions --shell powershell >> $PROFILE
```

---

**Q: What is `forc-migrate` for?**

When Sway introduces breaking language changes in a new version, `forc-migrate` automates migration of your source code. Run `forc migrate` and review the proposed changes before committing.

---

**Q: What does `forc plugins` show?**

It lists all `forc-*` plugin binaries installed on your system and found in PATH. Plugins extend `forc` with additional subcommands. The main plugins are: `forc-debug`, `forc-doc`, `forc-fmt`, `forc-lsp`, `forc-migrate`, `forc-publish`, `forc-tx`, `forc-client`.

---

**Q: How does Sway handle integer overflow?**

In debug mode, integer overflow causes a runtime revert. Use checked arithmetic from `std` for explicit overflow handling:

```sway
let result = a.checked_add(b).unwrap_or(u64::max());
```

---

**Q: Can I use Sway with a local Fuel node?**

Yes. Run a local `fuel-core` node and deploy with:

```bash
forc deploy --node-url http://localhost:4000
```

`fuel-core` is a separate binary managed by `fuelup`.

---

**Q: What is the `evm` build target?**

`forc build --build-target evm` compiles Sway to EVM bytecode instead of FuelVM. This is experimental. The primary and supported target is `fuel`.

---

**Q: What is `forc addr2line` used for?**

When a transaction fails at a specific opcode index, `forc addr2line` translates that index back to the source file and line number:

```bash
forc addr2line --contract-id 0x... --opcode-index 42
```

---

**Q: How does `forc template` work?**

```bash
forc template --url https://github.com/FuelLabs/sway-applications \
              --template-name counter \
              my-project
```

It fetches the git repository, extracts the named subdirectory as a template, and initializes a new project. A template is any standard Sway project hosted in a git repo.

---

**Q: Why does my library import show as `my_lib` when `Forc.toml` says `my-lib`?**

Hyphens in package names are automatically converted to underscores for use in Sway `use` statements. This matches Rust's convention. `my-lib` in `Forc.toml` becomes `my_lib` in source imports.

---

**Q: What is `forc parse-bytecode` for?**

It decodes a compiled `.bin` file into human-readable FuelVM opcodes. Useful for:
- Low-level debugging
- Verifying that a binary matches expected instructions
- Understanding what the compiler generated from your source

```bash
forc parse-bytecode out/debug/my-contract.bin
```

---

**Q: What are the `FORC_IMPLICIT_STD_*` env vars for?**

They override which version of the `std` library forc uses, without modifying `Forc.toml`. Primarily for toolchain developers testing against a custom or unreleased std build. Most users should never set these.

---

**Q: Is there a way to see what forc is doing internally?**

```bash
forc build --verbose          # more detailed output
forc build --time-phases      # phase-by-phase timing
forc build --print-ir initial # see IR before optimization
forc build --print-asm final  # see final assembly
forc build --metrics-outfile metrics.json  # write timing to JSON
```

These flags give progressively deeper visibility into the compilation pipeline.

---

**Q: How do I format only a specific file?**

```bash
forc fmt src/main.sw
```

Pass the file path as an argument to `forc fmt`.

---

**Q: What does `forc tx` do?**

`forc-tx` is a transaction builder plugin. It helps construct raw Fuel transactions for advanced use cases — primarily for tooling developers and protocol integrators who need direct transaction construction without a higher-level SDK.

---

**Q: Can I define multiple contracts in one Sway file?**

No. Each Sway source file has exactly one program type declaration, and a project has one entry point. Separate contracts must be in separate forc projects (or workspace members).

---

**Q: What happens to `forc build` output if I run it multiple times?**

The `out/` directory is overwritten on each successful build. Previous output for the same profile is replaced. Run `forc clean` if you want a completely fresh start with no cached artifacts.

---

**Q: How do I run a predicate?**

Predicates are not "run" directly — they are evaluated by the Fuel VM when a transaction attempts to spend a UTXO locked to that predicate's root hash. Use the Fuel Rust SDK (`fuels`) to construct and submit transactions that include predicate bytecode as part of the transaction inputs.

---

**Q: What is the difference between `forc new` and `forc init`?**

`forc new <path>` creates the directory and initializes a project inside it. `forc init` initializes a project in an existing directory (either the current directory or one specified with `--path`). Use `forc init` when the directory already exists and may already contain files you want to keep.

---

**Q: What does `--terse` do in forc build?**

`--terse` suppresses all informational output and only shows warnings and errors. Useful when integrating forc into scripts or pipelines where clean output is required, or when you want to focus on actionable diagnostic messages without surrounding noise.

---

**Q: How do I use a custom build profile?**

Define it in `Forc.toml`:

```toml
[build-profile.staging]
# custom profile settings
```

Then use it:

```bash
forc build --build-profile staging
```

---

**Q: What does the `--locked` flag do and when should I use it?**

`--locked` requires `Forc.lock` to already exist and match `Forc.toml` exactly. If they diverge, forc fails rather than silently updating the lock file. Always use `--locked` in CI to catch unintended dependency changes before they reach production.

---

_Generated May 2026 from FuelLabs/sway at e12e611. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
