# Sway keeps three versions apart: the docs you read, the Fuelup channel, and the forc you run

> A read of FuelLabs/sway: why the Sway Book's latest, vX.Y.Z and master labels are not the same thing as a Fuelup channel, what building the compiler from source actually costs, and how the justfile splits compiler benchmarks from gas and bytecode measurements.

**FuelLabs/sway** — Empowering everyone to build reliable and efficient smart contracts.

- Repository: https://github.com/FuelLabs/sway
- Website: https://docs.fuel.network/docs/sway/
- Stars: 61,420 · Forks: 5,413
- Language: Rust
- License: Apache-2.0
- Published: 2026-08-04 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/fuellabs-sway

## The docs carry a version label that is not your toolchain version

Sway publishes its book under three labels and then warns about reading them as anything else. `latest` redirects to the most recently published Sway release, `vX.Y.Z` is documentation built from that exact release tag, and `master` is built from the default branch and may describe unreleased behavior. The readme then draws the line explicitly: those labels are documentation versions, they are not Fuelup channel names, and they do not identify the toolchain activated on a Fuel network. The check it points to is the compiler itself, `forc --version`, with the Fuelup channel documentation as the place to decide which tooling a network needs.

A third source makes the mismatch more likely, not less. The Stable Sway and Forc pages on docs.fuel.network are published by a separate repository, FuelLabs/docs-hub, from an explicitly selected Sway release, and that selection can differ both from the newest upstream release and from the compiler in a named Fuelup channel. The standard library pages and the technical reference are served from the master path, so both can describe code that has not shipped. The cost lands on debugging: behaviour that contradicts your compiler gets looked up in a page that is answering a different question, and the page is not wrong, it is just about another build.

## Building the source builds the compiler, not your contracts

The build section says so in its first line: it is for developing the Sway compiler and toolchain, and anyone developing contracts is sent to the book instead, which is where release builds are installed. The dependency step is Rust stable, chosen explicitly rather than by whatever toolchain the machine happens to have.

```bash
rustup default stable
```

Then the Cargo binary directory goes on the path, and the readme is clear that the shell has to be restarted after editing the profile rather than reloaded.

```bash
export PATH="${HOME}/.cargo/bin:${PATH}"
```

The build itself clones over SSH, which rules out a plain anonymous clone without a key.

```bash
git clone git@github.com:FuelLabs/sway.git
cd sway
cargo build
```

The confirmation step runs the freshly built binary rather than an installed one, which is the part worth copying for a quick check.

```bash
cargo run --bin forc -- --help
```

That build is not small. The workspace at the root pulls in the compiler crates and the forc toolchain together, so a contract author who wanted one project ends up compiling the language itself.

## just drives the scripts, and three recipes stop to ask before running

Every other script in the repository is run through casey/just, and the default recipe is a listing rather than a build: bare `just` prints the available recipes unsorted. The readme shows a `just --list` excerpt grouped into automation, benchmark, build, ci and test, but that excerpt is smaller than the justfile, which also defines bisect-forc and the two performance recipes with their aliases pe2e and pil.

The detail that bites automation is the confirmation prompts. install-ci-check carries a prompt asking whether you want cargo-sort, cargo-generate and cargo-udeps installed from crates.io before it installs them, and update-fuel-dependencies and update-contract-ids each carry their own prompt before touching dependencies or contract ids. A pipeline that invokes those recipes without a terminal waits on a question it will never answer, and ci-check is the one that simply runs `bash ./ci_checks.sh`. Contributors are pointed at the Contributing To Sway chapter of the book for the workflow, so the recipe names in the readme are a starting point rather than the full surface.

## Compiler time and contract gas are measured by two different recipe groups

The justfile separates two questions that are easy to confuse. The benchmark group is about the compiler itself, and the file says so in a comment above it, citing compilation times. Those two recipes are plain shell calls, `./benchmark.sh` at the root and `./test/bench.sh` for the benchmark tests.

The performance group measures what the compiled code costs, described as gas usages and bytecode sizes, and it collects numbers from two sources. The e2e one runs the test package in release mode filtered to e2e and perf only:

```bash
cargo r -r -p test -- --release --kind e2e --perf-only --perf {{filter}}
```

The in-language one runs from a bash script that works out the current branch with `git rev-parse --abbrev-ref HEAD`, stamps a timestamp, and writes CSV files for gas usages and sizes into ./test/perf_out/ with the branch name in the filename. Consequence for a reviewer: a change that makes the compiler slower and a change that makes a contract more expensive show up in different places, and the in-language numbers arrive as dated CSV files to compare by hand rather than as a reported figure.

## Twenty workspace members share one version string, and examples/ is excluded

The workspace manifest lists twenty members with resolver 2: forc, forc-pkg, forc-plugins and everything under it, forc-test, forc-util, the mdbook documenter script, then the compiler crates sway-ast, sway-core, sway-error, sway-features, sway-ir, sway-ir-macros, sway-lsp, sway-parse, sway-types, sway-utils, swayfmt, and the test package. The exclude line is the part with teeth: `examples/*`, `swayfmt/test_macros`, and `forc-test/test_data` are all outside the workspace.

Two consequences follow. A root `cargo build` never compiles the example contracts, so anything broken in examples/ stays invisible until a just recipe builds them, and the build recipes that do exist are separate from the test recipes. Second, every internal dependency is declared as a path plus the same version, all of them 0.72.1, matching workspace.package, which carries edition 2021, the Apache-2.0 licence and Fuel Labs as authors. A fork that bumps a version has to touch every one of those internal dependency lines, since the numbers are not inherited automatically even though they agree.

## forc is a plugin host, and forc-migrate is the contract upgrade path

Read as a set of binaries rather than a single tool, forc is four crates plus a plugin directory. forc, forc-pkg, forc-test and forc-util carry the command itself, package handling and test support, and forc-plugins/ holds forc-debug, forc-doc, forc-fmt, forc-lsp, forc-migrate, forc-publish and forc-tx. The plugin set is the interesting part for anyone with existing code, because forc-migrate is a dedicated plugin for changing contracts written against an earlier version, and the readme's upgrade advice for documentation is the mirror image of that tool. forc-debug and forc-tx cover the interactive and on-chain sides of a contract, while forc-doc and forc-fmt handle the generated documentation and the source formatting that rustfmt.toml and clippy.toml sit next to.

The language pipeline is split the same way at the top level: sway-ast, sway-parse, sway-types, sway-ir with its own macros crate, sway-core, plus sway-error for diagnostics, sway-features for feature gates, and sway-utils. The editor integration is a separate crate, sway-lsp, so the language server versions with the compiler rather than with an editor plugin. Repository hygiene config sits alongside: .markdownlint.yaml for the docs, .typos.toml for spelling, clippy.toml and rustfmt.toml for Rust, and a .devcontainer plus .vscode directory for environments.

## Apache-2.0 covers the toolchain, and the examples show which Fuel features are demonstrated

Licensing is the easy part here. The manifest sets Apache-2.0 in workspace.package and a LICENSE file sits at the root, so the compiler, the forc crates and the tooling in this repository are covered by it. That licence reaches the code in this tree, not the external services or the Fuel network itself.

The examples directory is the better guide to what the language is exercised against. The named cases include basic_storage_variables, advanced_storage_variables and nested_storage_variables for the storage model, abi_superabis and abi_supertraits for the ABI layer, identity, native_asset, msg_sender and multi_contract_calls for the call and asset surface, cei_analysis for ordering checks, configurable_constants, a liquidity_pool case as a realistic contract, and asm_return_tuple_pointer for low level output. Alongside them are the language basics, arrays, hashing, option, enums, match_expressions, counter, fizzbuzz, converting_types, break_and_continue and methods_and_associated_functions. Development is active, with the last push on 2026-09-24 and v0.72.1 published on 2026-08-28 after v0.72.0 on 2026-07-27. The list of examples is alphabetical and the tree view is cut off partway through, so a missing directory is not evidence that a feature is unsupported.

## Conclusion

Contract authors should install a released toolchain and read the Sway Book for that release rather than the master branch pages, and should confirm what `forc --version` reports before trusting behaviour described in docs. Compiler contributors can follow the documented build, but budget for a full workspace build and remember the examples/ tree is excluded from the workspace. Anyone writing code against the standard library should check the matching std documentation path, because the master copy can describe unreleased behaviour.

## FAQ

### How do I find out which Sway compiler I am actually running?

Run `forc --version`. The readme states that the latest, vX.Y.Z and master labels on the documentation site are documentation versions only, that they are not Fuelup channel names, and that they do not identify the toolchain activated on a Fuel network, so the compiler binary is the only reliable answer.

### Do I need to build Sway from source to write a contract?

No, the build section is explicitly for developing the compiler and toolchain, and installing release builds is covered in the latest released Sway Book. The source path, if you want it, is `rustup default stable`, a PATH export, a clone, `cargo build`, then `cargo run --bin forc -- --help` to confirm it built.

### How do I run the Sway benchmarks?

Through casey/just rather than raw scripts. The benchmark group covers the compiler, running ./benchmark.sh and ./test/bench.sh, while the performance group with the aliases pe2e and pil collects gas usages and bytecode sizes from e2e and in-language tests and writes them as CSV files under ./test/perf_out/.

## Sources

- [Official documentation](https://docs.fuel.network/docs/sway/)
- [Official README](https://github.com/FuelLabs/sway#readme)
- [Project repository](https://github.com/FuelLabs/sway)
- [Release notes](https://github.com/FuelLabs/sway/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/fuellabs-sway
