# How to run Swift code on Linux in a sandbox Install the Swift toolchain for Ubuntu 24.04 in a Linux microVM, then compile with `swiftc` or `swift build` and run the result there. **On Runtime, you install Swift once in an image, and every sandbox starts with the compiler ready.** Each sandbox is a Firecracker microVM running Ubuntu 24.04.5, the same release that swift.org builds its Ubuntu 24.04 toolchain for. Building an image is free. Swift 6.4.1 was the current release on 26 October 2026. Its Ubuntu 24.04 toolchain download is 1,124,788,555 bytes. ## Ways to get Swift Swift is not in the default image, and Ubuntu 24.04 (noble) has no `swiftlang` package (Ubuntu's archive, 26 October 2026). Use swift.org's builds: | Route | What you run | Good for | | ---------------------------------- | ---------------------------------------------------------------- | ---------------------------- | | The swift.org tarball | `curl` it and unpack it over `/`, as swift.org's Dockerfile does | Images and scripted installs | | swiftly, Swift's toolchain manager | `swiftly init --assume-yes --quiet-shell-followup` | Switching versions | | The official Docker image | `swift:6.4-noble` on Docker Hub as the image | A ready image with no recipe | The toolchain needs these Ubuntu 24.04 packages, as swift.org lists them: `binutils git gnupg2 libc6-dev libcurl4-openssl-dev libedit2 libgcc-13-dev libncurses-dev libpython3-dev libsqlite3-0 libstdc++-13-dev libxml2-dev libz3-dev pkg-config tzdata zip unzip zlib1g-dev` ([Swift on Linux](https://www.swift.org/install/linux/tarball/)). ## Build a Swift image The recipe installs the dependencies with `apt`, then unpacks the toolchain with `commands`. Commands run as root, as they do in swift.org's own Dockerfile. A build machine has 4 GiB of scratch disk by default. You can request up to 32 GiB ([image limits](/docs/images#limits)), so this recipe asks for 16 GiB. ```ts check import { Runtime } from "withruntime"; const deps = [ "binutils", "git", "gnupg2", "libc6-dev", "libcurl4-openssl-dev", "libedit2", "libgcc-13-dev", "libncurses-dev", "libpython3-dev", "libsqlite3-0", "libstdc++-13-dev", "libxml2-dev", "libz3-dev", "pkg-config", "tzdata", "zip", "unzip", "zlib1g-dev", ]; const url = "https://download.swift.org/swift-6.4.1-release/ubuntu2404/swift-6.4.1-RELEASE/swift-6.4.1-RELEASE-ubuntu24.04.tar.gz"; const runtime = new Runtime(); await runtime.images.build( { name: "swift", build: { diskMiB: 16384 }, recipe: { apt: deps, commands: [ `curl -fsSL ${url} | tar -xz -C / --strip-components=1`, "chmod -R o+r /usr/lib/swift && swift --version", ], }, }, { onLog: (line) => console.log(line.text) }, ); ``` ```python check from withruntime import Runtime deps = ["binutils", "git", "gnupg2", "libc6-dev", "libcurl4-openssl-dev", "libedit2", "libgcc-13-dev", "libncurses-dev", "libpython3-dev", "libsqlite3-0", "libstdc++-13-dev", "libxml2-dev", "libz3-dev", "pkg-config", "tzdata", "zip", "unzip", "zlib1g-dev"] url = ("https://download.swift.org/swift-6.4.1-release/ubuntu2404/" "swift-6.4.1-RELEASE/swift-6.4.1-RELEASE-ubuntu24.04.tar.gz") runtime = Runtime() runtime.images.build(name="swift", build={"disk_mib": 16384}, recipe={ "apt": deps, "commands": [ f"curl -fsSL {url} | tar -xz -C / --strip-components=1", "chmod -R o+r /usr/lib/swift && swift --version", ], }, on_log=lambda line: print(line["text"])) ``` The toolchain lands in `/usr/bin` and `/usr/lib/swift`, as in the official image. swift.org also publishes a `.sig` signature beside each tarball, which its Dockerfile checks with `gpg` before unpacking. ## Compile and run a program Start a sandbox from the image, write the source, compile, then run the binary with the network off. ```ts check import { Sandbox } from "withruntime"; const source = ` struct Point { var x: Double, y: Double } let points = [Point(x: 3, y: 4), Point(x: 6, y: 8)] let lengths = points.map { ($0.x * $0.x + $0.y * $0.y).squareRoot() } print(lengths) `; await using sbx = await Sandbox.create({ image: "swift", diskMiB: 10240, network: { internet: false }, timeoutSeconds: 600, onLeaseEnd: "stop", }); await sbx.files.write("/workspace/main.swift", source); const build = await sbx.exec(["swiftc", "-O", "main.swift", "-o", "main"], { timeoutMs: 300_000 }); if (build.exitCode !== 0) throw new Error(build.stderr); const run = await sbx.exec(["./main"], { timeoutMs: 10_000 }); console.log(run.stdout); // [5.0, 10.0] ``` ```python check from withruntime import Sandbox source = """ struct Point { var x: Double, y: Double } let points = [Point(x: 3, y: 4), Point(x: 6, y: 8)] let lengths = points.map { ($0.x * $0.x + $0.y * $0.y).squareRoot() } print(lengths) """ with Sandbox.create(image="swift", disk_mib=10240, network={"internet": False}, timeout_seconds=600, on_lease_end="stop") as sbx: sbx.files.write("/workspace/main.swift", source) build = sbx.exec(["swiftc", "-O", "main.swift", "-o", "main"], timeout_ms=300_000) if build.exit_code != 0: raise SystemExit(build.stderr) print(sbx.exec(["./main"], timeout_ms=10_000).stdout) ``` - **Disk:** a sandbox's `diskMiB` includes the image, so request more than the default 4 GiB. Without credit, a sandbox has up to 10 GiB ([free usage](/docs/included-usage)). - **Compile time:** set its own `timeoutMs` on `swiftc`. The default, 60 seconds, is meant for quick commands. - **Errors:** `swiftc` prints each diagnostic with file, line and column on stderr, so you can return it to a model unchanged. ## Test a Swift package For a package with a `Package.swift`, resolve dependencies with the network on, then build and test offline: ```ts check import { Sandbox } from "withruntime"; await using sbx = await Sandbox.create({ image: "swift", diskMiB: 10240, timeoutSeconds: 1800 }); await sbx.files.upload("./MyLibrary", "/workspace/MyLibrary"); const opts = { cwd: "/workspace/MyLibrary", timeoutMs: 900_000 }; await sbx.exec(["swift", "package", "resolve"], { ...opts, check: true }); await sbx.network.set({ internet: false }); const tests = await sbx.exec(["swift", "test"], { ...opts, onStdout: (t) => process.stdout.write(t), }); process.exitCode = tests.exitCode ?? 1; ``` Linux has no Apple frameworks, such as UIKit or SwiftUI. So this covers server-side and command-line Swift: the standard library, Foundation, and packages that build on Linux. ## Without an image In a plain sandbox, run the same steps with `sudo`: `sudo apt-get update`, `sudo apt-get install -y` for the dependencies, then `curl -fsSL | sudo tar -xz -C / --strip-components=1`. Or use swiftly, which installs into `$HOME/.local/share/swiftly` by default. Its `--assume-yes` option skips the prompts ([swiftly reference](https://github.com/swiftlang/swiftly)). ## What it costs Compiling uses CPU. Waiting does not. Runtime bills measured CPU at $0.025 per vCPU-hour, with a floor of a twentieth of a vCPU, and memory at $0.0075 per GiB-hour ([pricing](/docs/pricing)). A stored image is charged by its size. An account without credit can store its first three images free. A new account gets 100 free hours of a 1 GB machine in its first 30 days, with no card required. See also [how to run C++ code in a sandbox](/languages/cpp), [a coding agent sandbox](/use-cases/coding-agent-sandbox) and [running untrusted LLM code](/use-cases/run-untrusted-llm-code). ## Sources Checked 26 October 2026. - [Install Swift on Linux](https://www.swift.org/install/linux/) (Swift 6.4.1, swiftly commands), [tarball dependencies for Ubuntu 24.04](https://www.swift.org/install/linux/tarball/) - [swift-docker Dockerfile for 6.4 on Ubuntu 24.04](https://github.com/swiftlang/swift-docker/blob/main/6.4/ubuntu/24.04/Dockerfile) (tarball URL and signature check); the tarball's size from its `Content-Length` header - [swiftly command reference](https://github.com/swiftlang/swiftly/blob/main/Documentation/SwiftlyDocs.docc/swiftly-cli-reference.md) - [swift on Docker Hub](https://hub.docker.com/_/swift) (tag `6.4-noble`); [packages.ubuntu.com, noble](https://packages.ubuntu.com/noble/swiftlang): no `swiftlang` package Facts on this page were checked on 26 October 2026.