Installing Sailfin
Just want the binary? Head to the Downloads page for pre-built binaries for every supported platform, or keep reading for the recommended install script.
Requirements
Section titled “Requirements”Sailfin runs on the following platforms:
| Platform | Architectures | Tier |
|---|---|---|
| Linux | x86_64 | Tier 1 — primary |
| Linux | arm64 (aarch64) | Tier 2 — supported |
| macOS | arm64 (Apple Silicon) | Tier 2 — supported |
| Windows | x86_64 | Tier 2 — supported |
These are the platform assets produced by the release workflow. The scripts can detect additional architectures, but installation stops when the selected release does not contain a matching archive. WSL on an x86_64 Windows host uses the Linux x86_64 asset; Git Bash installs the Windows x86_64 asset.
This table describes base support: published toolchains backed by platform validation. It is not a capability-seal claim. Linux arm64 is a Tier 2 base target, but owned syscalls and a fully gated syscall boundary are not supported there.
Windows is a Tier 2 target. Current Windows x86_64 releases publish one native MSVC asset with TLS and networking support. Every source PR builds the native compiler and runs the eight owned Windows test shards; the nightly workflow additionally proves the strict self-host fixed point and complete cold suite. The
x86_64-w64-mingw32backend remains supported for explicit cross compilation and is covered by its Linux build plus a Windows smoke test, but it is not used to bootstrap or package releases. Windows arm64 is not currently supported. WSL remains available when a Linux environment is preferred.
Compiler and linker tools
Section titled “Compiler and linker tools”The installer only downloads and places the released sfn binary. To compile,
run, or test Sailfin programs, the current backend still needs LLVM tools 17+
or 18+ plus clang and the platform linker. Release binaries do not bundle
LLVM/clang.
The installer script itself also requires curl, tar, uname, mktemp, and
jq on Linux/macOS because it selects release assets through the GitHub API.
install.sh additionally requires an OpenSSL 3.0+ build (raw Ed25519
verification via pkeyutl -rawin needs 3.0) to verify the signed release
manifest; it probes $SAILFIN_OPENSSL, openssl on PATH, and the Homebrew
openssl@3 keg paths before giving up. install.ps1 needs no external
verification tooling — its Ed25519 verifier is embedded pure PowerShell.
If you are building Sailfin itself from source, you also need bash,
OpenSSL development libraries, and the source-build dependencies listed in
Building from source.
Quick Install (recommended)
Section titled “Quick Install (recommended)”Linux and macOS
Section titled “Linux and macOS”Paste the following into a terminal:
curl -fsSL https://raw.githubusercontent.com/SailfinIO/sailfin/main/install.sh | bashThe script will:
- Detect your OS and architecture
- Download the latest matching release binary from GitHub Releases
- Install
sailfinandsfnto~/.local/bin - Print confirmation when complete
Bootstrap security: The install script fails closed. It embeds the Sailfin release-signing public key and verifies the release before downloading the archive: it fetches
SHA256SUMSandSHA256SUMS.sig, checks the Ed25519 manifest signature (requiring a KAT-passing OpenSSL 3.0+ on Linux/macOS; a self-contained embedded verifier on Windows, no external tooling needed), then checks the archive’s SHA-256 digest. A missing manifest/signature, a fetch that could not be reached at all, or no KAT-passing verifier on the host all abort the install. SetSAILFIN_ALLOW_UNVERIFIED=1to explicitly consent to installing an unverified artifact anyway (an older unsigned release, or — on Linux/macOS only — a host with no working verifier;install.ps1embeds its verifier, so no Windows host is in that state) — it never bypasses a failed signature or a digest mismatch. To verify manually instead, follow Verifying Your Download. Subsequentsfn toolchain installdownloads verify both the Ed25519 signature and SHA-256 digest automatically (fail-closed).
Example output (abridged — every real line is prefixed with a timestamp, shown
here as [...]):
[...] Detected OS: linux[...] Detected ARCH: x86_64...[...] Installed: ~/.local/share/sailfin/versions/x86_64-unknown-linux-gnu/<version>/sailfin[...] entry toolchain: <version> (~/.local/bin/sfn)[...] default toolchain: none recorded; unpinned commands use the entry toolchain[...] Manage this installation natively:[...] sfn toolchain active[...] sfn toolchain update --check[...] sfn toolchain default <version>[...] This installer is the one-time on-ramp onto management protocol 1.[...] An 'sfn' predating that protocol cannot route the native lifecycle[...] commands, so crossing over takes one run of this installer or of your[...] package manager's upgrade. After that, 'sfn toolchain update' is the[...] supported update path, and it never replaces this entry executable.Windows (PowerShell)
Section titled “Windows (PowerShell)”Paste the following into a PowerShell terminal (PowerShell 5.1+ or PowerShell 7+):
irm https://raw.githubusercontent.com/SailfinIO/sailfin/main/install.ps1 | iexThe script installs sailfin.exe and sfn.exe to
%LOCALAPPDATA%\sailfin\bin and adds that directory to your user PATH
automatically. You do not need to run PowerShell as Administrator.
Example output (abridged — every real line is prefixed with a timestamp, shown
here as [...]):
[...] Detected OS: windows[...] Detected ARCH: x86_64...[...] Installed: C:\Users\you\AppData\Local\sailfin\versions\x86_64-pc-windows-msvc\<version>\sailfin.exe[...] entry toolchain: <version> (C:\Users\you\AppData\Local\sailfin\bin\sfn.exe)[...] default toolchain: none recorded; unpinned commands use the entry toolchain[...] Manage this installation natively:[...] sfn toolchain active[...] sfn toolchain update --check[...] sfn toolchain default <version>[...] This installer is the one-time on-ramp onto management protocol 1.[...] An 'sfn' predating that protocol cannot route the native lifecycle[...] commands, so crossing over takes one run of this installer or of your[...] package manager's upgrade. After that, 'sfn toolchain update' is the[...] supported update path, and it never replaces this entry executable.Windows users: Restart your terminal after installation so that the updated
PATHtakes effect. If you use Windows Terminal, close and reopen the window.
Verifying the Installation
Section titled “Verifying the Installation”After installing, run:
sfn --versionExpected output:
sfn <version>If the command is not found, see Troubleshooting below.
Pinning a Version
Section titled “Pinning a Version”Sailfin is pre-1.0, so pin exact release versions in CI and reproducible setup
scripts. Omit VERSION for the latest release asset that matches your platform.
Compiler repository development uses the exact seed version in
bootstrap.toml,
not a hard-coded docs-page version.
Linux and macOS
Section titled “Linux and macOS”Replace the example version with the release you want to pin:
VERSION=0.8.0curl -fsSL https://raw.githubusercontent.com/SailfinIO/sailfin/main/install.sh | VERSION="$VERSION" bashYou can also pass the version as an install-script argument:
VERSION=0.8.0curl -fsSL https://raw.githubusercontent.com/SailfinIO/sailfin/main/install.sh | bash -s -- --version "$VERSION"Windows (PowerShell)
Section titled “Windows (PowerShell)”Replace the example version with the release you want to pin:
$env:VERSION = "0.8.0"irm https://raw.githubusercontent.com/SailfinIO/sailfin/main/install.ps1 | iexSet $env:VERSION before invoking iex so the script reads it.
Why pin? The Sailfin project is marching toward a 1.0 release. Alpha builds may include regressions as large parts of the compiler and runtime are rewritten. Pinning gives CI and onboarding scripts a reproducible toolchain.
Verification and mirror environment variables
Section titled “Verification and mirror environment variables”Both install scripts accept a few env vars beyond VERSION/REPO/GITHUB_TOKEN:
| Variable | Effect |
|---|---|
SAILFIN_OPENSSL |
Path to an OpenSSL 3.0+ binary to try first as the signature verifier (Linux/macOS only). |
SAILFIN_RELEASE_BASE |
Overrides where SHA256SUMS, SHA256SUMS.sig, and the archive are fetched from (files read from <base>/<tag>/). Changes location only — verification stays mandatory and the trust anchor is never overridable. |
SAILFIN_LOCAL_ARCHIVE |
Installs a tarball already on disk instead of a published release. Requires an explicit VERSION. |
SAILFIN_LOCAL_ARCHIVE_SHA256 |
Pins SAILFIN_LOCAL_ARCHIVE to a caller-supplied SHA-256, reaching trust state DIGEST_PINNED instead of requiring the opt-in below. |
SAILFIN_ALLOW_UNVERIFIED=1 |
Consent to install an artifact whose signature chain cannot be established: an unsigned historical release, a local archive with no pinned digest, or (Linux/macOS only) no KAT-passing Ed25519 verifier on the host. Never bypasses a failed signature, a digest mismatch, a malformed manifest, or an unreachable manifest — those abort regardless. |
See Verifying Your Download for the full trust-state model.
What Gets Installed
Section titled “What Gets Installed”The installer places two binaries in the install directory. They are identical —
sfn is a shorter alias for sailfin:
| Binary | Purpose |
|---|---|
sailfin |
The full compiler and toolchain |
sfn |
Alias for sailfin; most examples and docs use sfn |
Default install locations
Section titled “Default install locations”| Platform | Directory |
|---|---|
| Linux / macOS | ~/.local/bin |
| Windows | %LOCALAPPDATA%\sailfin\bin |
You can override the install directory by setting GLOBAL_BIN_DIR before running
the script:
curl -fsSL https://raw.githubusercontent.com/SailfinIO/sailfin/main/install.sh | GLOBAL_BIN_DIR=/usr/local/bin bashConfirming the binaries are on PATH
Section titled “Confirming the binaries are on PATH”which sfnsfn --version# sfn <version>On Windows:
Get-Command sfn# CommandType Name SourceManual Installation
Section titled “Manual Installation”If you cannot run the install script (e.g., in an air-gapped environment), you can download and place the binary manually. The Downloads page lists every platform binary with direct download links.
Step 1: Find the release asset
Section titled “Step 1: Find the release asset”Go to the Downloads page or directly to github.com/SailfinIO/sailfin/releases and locate the release you want to install. Release assets follow this naming convention:
sailfin_<version>_<os>_<arch>.tar.gzExamples:
| Asset name | Platform |
|---|---|
sailfin_${VERSION}_linux_x86_64.tar.gz |
Linux x86_64 |
sailfin_${VERSION}_linux_arm64.tar.gz |
Linux arm64 (aarch64) |
sailfin_${VERSION}_macos_arm64.tar.gz |
macOS Apple Silicon |
sailfin_${VERSION}_windows_x86_64-msvc.tar.gz |
Windows x86_64 (native MSVC) |
Current Windows x86_64 releases publish only the -msvc asset. Historical
releases before native MSVC bootstrapping may instead use the plain
windows_x86_64.tar.gz name; that legacy artifact is not produced by the
current release workflow.
Step 2: Verify the download
Section titled “Step 2: Verify the download”Download the tarball together with SHA256SUMS and SHA256SUMS.sig, then
verify the manifest signature and the tarball digest before extracting it. The
download verification guide provides
copy-pasteable OpenSSL commands and publishes the canonical signing key and
fingerprint.
VERSION=0.8.0
# Download (replace the filename with the one that matches your platform)curl -LO "https://github.com/SailfinIO/sailfin/releases/download/v${VERSION}/sailfin_${VERSION}_linux_x86_64.tar.gz"curl -LO "https://github.com/SailfinIO/sailfin/releases/download/v${VERSION}/SHA256SUMS"curl -LO "https://github.com/SailfinIO/sailfin/releases/download/v${VERSION}/SHA256SUMS.sig"Do not extract the archive unless both verification steps succeed.
Step 3: Extract and place the binary
Section titled “Step 3: Extract and place the binary”VERSION=0.8.0
# Extracttar -xzf "sailfin_${VERSION}_linux_x86_64.tar.gz"
# The archive contains bin/sailfin and bin/sfn# Move them to a directory on your PATHmkdir -p ~/.local/bincp bin/sailfin ~/.local/bin/sailfincp bin/sfn ~/.local/bin/sfnchmod +x ~/.local/bin/sailfin ~/.local/bin/sfnStep 4: Verify the installed command
Section titled “Step 4: Verify the installed command”sfn --version# sfn <version>Building from Source
Section titled “Building from Source”Building from source is useful when:
- You are contributing to the compiler
- You need a build for an unsupported platform
- You want to test unreleased changes
Prerequisites
Section titled “Prerequisites”git,bashcurl,tar,mktemp,uname,jq- LLVM tools 17+ or 18+ (
llvm-link,llvm-as) clangand the platform linkershasum -a 256orsha256sum
See the compiler/runtime development setup for per-platform package commands and the complete supported build flag table.
# Clone the repositorygit clone https://github.com/SailfinIO/sailfin.gitcd sailfin
# Install a released sfn (a clean checkout has none, and the next step needs one)./install.sh
# Build the native compiler by self-hosting from the released seed pinned in bootstrap.tomlsfn dev bootstrap build
# Install the local self-build to ~/.local/binbuild/bin/sfn dev bootstrap install --from build/bin/sfn --prefix "$HOME/.local"After installing, verify with:
sfn --versionYou can also run the binary directly without installing:
build/bin/sfn --versionUse another --prefix to choose a different installation root. Packagers can
add --destdir <staging-root>; a /usr/local prefix then lands beneath the
stage as <staging-root>/usr/local/bin/sfn. The native install command refuses
to overwrite an unmarked or externally changed live entry because it may be
owned by a package manager. It also installs the runtime and compiler capsule
closure beside the executable so the PATH command works outside the source
checkout.
Note:
sfn dev bootstrap buildroutes through<seed> build -p compiler— the Sailfin-native driver — and requiresbash,clang, LLVM tools, andjq. The priorscripts/build.shorchestrator is no longer in-tree.
Updating
Section titled “Updating”Entry toolchain, selected toolchain, and the one-time upgrade
Section titled “Entry toolchain, selected toolchain, and the one-time upgrade”The sfn this installer places on PATH is the entry toolchain: a stable
router that reads the recorded default (or a project’s [toolchain] pin) and
dispatches to the selected toolchain — the exact versioned payload that
actually parses and runs an ordinary command. Starting with the first release
whose install manifest carries management protocol 1, the entry toolchain
also routes sfn toolchain ... itself to the newest compatible installed
payload instead of handling it directly, so later sfn toolchain update
installs can add management commands without ever replacing the entry
executable on PATH. The installer does not record a per-user default for
you — with none recorded, unpinned commands fall back to running the entry
toolchain directly. See Toolchain Pinning
Flags in the CLI reference for
the full selection precedence and management-routing behavior.
This router is new behavior, and a sfn installed before it shipped cannot
learn it after the fact — an old entry executable only understands the
command tree it was built to parse, and the router is one of the things it
was never built to parse. Adopting it therefore requires one explicit
entry upgrade: re-run this installer, or upgrade through the package manager
that owns your sfn, one time. From the first release that carries
management protocol 1 onward, sfn toolchain update is the supported way to
move forward, and it never replaces the entry executable itself.
Re-running the installer
Section titled “Re-running the installer”To perform that one-time entry upgrade — or to install for the first time — re-run the install script. It overwrites the existing binaries in-place:
# Linux / macOS: update to latestcurl -fsSL https://raw.githubusercontent.com/SailfinIO/sailfin/main/install.sh | bash
# Linux / macOS: update to a specific versionVERSION=0.8.0curl -fsSL https://raw.githubusercontent.com/SailfinIO/sailfin/main/install.sh | VERSION="$VERSION" bash# Windows: update to latestirm https://raw.githubusercontent.com/SailfinIO/sailfin/main/install.ps1 | iexRe-running the installer replaces the entry toolchain but never touches a
per-user default you have already recorded. If one exists, the completion
output says so instead of reporting none recorded, because that default —
not the release you just installed — is what unpinned commands will select.
Run sfn toolchain active to see which toolchain
wins, and sfn toolchain default <version> to move it.
As with the initial install, pinning to a known release version is recommended
for CI and reproducible environments. Once your entry toolchain carries
management protocol 1, prefer sfn toolchain update for day-to-day updates
instead of re-running this script.
Uninstalling
Section titled “Uninstalling”Delete the binaries from the install directory:
# Linux / macOSrm ~/.local/bin/sailfin ~/.local/bin/sfn# WindowsRemove-Item "$env:LOCALAPPDATA\sailfin\bin\sailfin.exe"Remove-Item "$env:LOCALAPPDATA\sailfin\bin\sfn.exe"You may also want to remove %LOCALAPPDATA%\sailfin (Windows) or the now-empty
~/.local/bin entries from your shell profile, if applicable.
Troubleshooting
Section titled “Troubleshooting”sfn: command not found after installation
Section titled “sfn: command not found after installation”The install directory is not on your PATH. Check which shell you are using and
add the directory:
bash (~/.bashrc or ~/.bash_profile):
export PATH="$HOME/.local/bin:$PATH"zsh (~/.zshrc):
export PATH="$HOME/.local/bin:$PATH"After editing the file, reload it:
source ~/.bashrc # or ~/.zshrcOn macOS, if you installed globally to /usr/local/bin, that directory is usually
already on PATH. Confirm with echo $PATH.
Permission denied when running the binary (Linux / macOS)
Section titled “Permission denied when running the binary (Linux / macOS)”The binary may not be marked executable. Fix it:
chmod +x ~/.local/bin/sailfin ~/.local/bin/sfnMissing LLVM or clang during a build
Section titled “Missing LLVM or clang during a build”Install the source-build dependencies for your platform:
# Ubuntu / Debiansudo apt-get install clang-18 llvm-18 jq
# Fedora / RHELsudo dnf install clang llvm llvm-devel jq
# macOS (Homebrew)brew install jq llvmIf Homebrew LLVM is installed but llvm-link is not detected, put it on PATH:
export PATH="$(brew --prefix llvm)/bin:$PATH"GitHub API rate limiting during install
Section titled “GitHub API rate limiting during install”The install script calls the GitHub Releases API to find the latest version. If you hit rate limits (common in CI environments), set a GitHub token:
curl -fsSL https://raw.githubusercontent.com/SailfinIO/sailfin/main/install.sh | GITHUB_TOKEN=ghp_your_token_here bashAlternatively, pin the version explicitly with VERSION=<version> — this
constructs the asset name directly and can avoid the release-list lookup.
Windows: script execution policy
Section titled “Windows: script execution policy”If PowerShell refuses to run the install script, you may need to allow remote scripts for the current session:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypassirm https://raw.githubusercontent.com/SailfinIO/sailfin/main/install.ps1 | iexThis change only affects the current PowerShell session and does not persist.
Next Steps
Section titled “Next Steps”- Downloads — Pre-built binaries for every platform
- Verifying Your Download — Verify release signatures and checksums
- Toolchain Pinning Flags — Manage what you just installed:
sfn toolchain active,list,update --check, anddefault - Editor Setup — Install the Sailfin VS Code extension for syntax highlighting and snippets
- Hello, World! — Write and run your first Sailfin program
- Tour of Sailfin — A guided introduction to the language