Swift Module 1 – Getting started: Swift 6.4, toolchains and your first program
Install Swift 6.4 on macOS, Linux and Windows
Install a Swift 6.4 toolchain on macOS, Linux or Windows, choose between Xcode, the Command Line Tools and swiftly, and prove which compiler you run.
What you will learn
- Install a Swift 6.4 toolchain on macOS, Linux or Windows from its official source
- Choose between Xcode, the Command Line Tools and swift.org toolchains managed by swiftly
- Check which compiler, language mode and libraries a build really uses, with swift --version and a doctor program
- Set up an editor that understands Swift through SourceKit-LSP
Before you start
What you’ll learn · Before you start
What you will learn
- Install a Swift 6.4 toolchain on macOS, Linux or Windows from its official source
- Choose between Xcode, the Command Line Tools and swift.org toolchains managed by swiftly
- Check which compiler, language mode and libraries a build really uses, with swift --version and a doctor program
- Set up an editor that understands Swift through SourceKit-LSP
Before you start
On this page
Two people can both “have Swift” and still see different results: one Mac runs the Swift 6.3 of Xcode 26.6, another the Swift 6.4 of the Command Line Tools: Apple's package of the command-line compilers and the macOS SDK that ship with Xcode, without Xcode itself. xcode-select --install puts it in /Library/Developer/CommandLineTools., and a Linux server something else again. Every output in this track was printed by Swift 6.4, so your first job is a Swift 6.4 toolchain: The programs of one Swift release that turn source code into running programs: the compiler, the standard library, the Swift Package Manager and tools such as LLDB and SourceKit-LSP., and your second is proof of which compiler your terminal and your editor really run.
This lesson installs Swift on macOS, Linux or Windows from the official sources, helps you choose between Xcode, the Command Line Tools and swiftly: The command-line tool of swift.org that installs Swift toolchains on macOS and Linux, keeps several side by side and switches between them with swiftly use., and ends with a small doctor program that reports the compiler, the language mode and the libraries a build can use.
On a Mac: Xcode, the Command Line Tools or swiftly
A Mac offers three sources of Swift, and they differ in what they include:
- Xcode 27 contains Swift 6.4, the SDKs of every Apple platform, and Apple’s editor and debugger. It needs macOS Tahoe 26.6 or later, and of the three it is the one that builds app projects for iPhone and iPad.
- The Command Line Tools are Apple’s smaller package of the command-line compilers and the macOS SDK that ship with
Xcode.
xcode-select --installinstalls them into/Library/Developer/CommandLineTools. Commands such asxcodebuildcome only with Xcode, and only one version of the package can be installed at a time. - A swift.org toolchain, installed and switched with swiftly. The macOS install page downloads swiftly as a package
and sets it up with
swiftly init; swiftly then installs releases such as 6.4.1, and development snapshots, side by side. Swift.org says its toolchains support the Static Linux SDK and include experimental features such as Embedded Swift and WebAssembly support.
The Command Line Tools ran every session of this track. This session asks the toolchain what it is and what it holds:
from session import run, version
# Which swift the shell runs, where it comes from, and what that toolchain holds. The last command is meant to fail.
version()
run("""
which -a swift
swift --version
xcode-select -p
swift package --version
ls /Library/Developer/CommandLineTools/usr/bin | grep -E '^(swift|swiftc|swift-format|sourcekit-lsp|lldb)$'
ls /Library/Developer/CommandLineTools/Library/Developer/Frameworks
!xcrun --find docc
""") Output
# Apple Swift version 6.4 (swiftlang-6.4.0.34.1) $ which -a swift /usr/bin/swift $ swift --version swift-driver version: 1.168.6 Apple Swift version 6.4 (swiftlang-6.4.0.34.1 clang-2100.3.34.1) Target: arm64-apple-macosx26.0 $ xcode-select -p /Library/Developer/CommandLineTools $ swift package --version Swift Package Manager - Swift 6.4.0-dev $ ls /Library/Developer/CommandLineTools/usr/bin | grep -E '^(swift|swiftc|swift-format|sourcekit-lsp|lldb)$' lldb sourcekit-lsp swift swift-format swiftc $ ls /Library/Developer/CommandLineTools/Library/Developer/Frameworks _Testing_AppKit.framework _Testing_CoreGraphics.framework _Testing_CoreImage.framework _Testing_CoreTransferable.framework _Testing_Foundation.framework _Testing_UIKit.framework Testing.framework $ xcrun --find docc xcrun: error: unable to find utility "docc", not a developer tool or in PATH [exit status 72]
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 toolchain_session.py
/usr/bin/swift is the only swift on this computer’s path, and it runs the toolchain that xcode-select -p names,
here the Command Line Tools. The compiler reports 6.4, while the package manager prints its own build name, 6.4.0-dev.
The tools folder holds swift, swiftc, swift-format, sourcekit-lsp and lldb; the frameworks folder holds Swift
Testing, Testing.framework, but no XCTest; and xcrun finds no docc, the documentation compiler. XCTest comes with
Xcode, and DocC with Xcode or with the toolchains of swift.org.
Apple’s Swift Playground app for iPad and Mac is a gentle way to start, and it builds apps with SwiftUI. Its page names no Swift version, so when its output differs from a session here, compare the versions first.
Checkpoint
Check: Swift on a Mac
On Linux and Windows: swiftly, a container or winget
On Linux, the swift.org install page starts with swiftly, which manages Swift and its dependencies:
- Download and unpack it:
curl -O https://download.swift.org/swiftly/linux/swiftly-$(uname -m).tar.gz, thentar zxf swiftly-$(uname -m).tar.gz. - Run
./swiftly init --quiet-shell-followup, which sets swiftly up and installs the newest release, then load the environment file it names, as the install page shows for your shell. - Later,
swiftly install 6.4.1adds a release andswiftly use 6.4.1makes it the one your shell runs.
Containers are the other way. The official image is called swift, and its tags name the release and the Linux
distribution:
| Tag | What the container holds |
|---|---|
swift:6.4-noble |
Swift 6.4 on Ubuntu 24.04 |
swift:6.4-bookworm |
Swift 6.4 on Debian 12 |
swift:6.4-noble-slim |
Only the libraries that run Swift programs, no compiler |
swift:latest |
Whatever is newest: it moves to each new release and distribution |
Pin a tag with both names in anything you build, so that your compiler changes only when you change the tag.
docker run --cap-add sys_ptrace -it --rm swift swift starts a Swift REPL in a throwaway container.
On Windows, swift.org installs the platform’s dependencies first and Swift second, both with winget:
winget install --id Microsoft.VisualStudio.2022.Community --exact --force --custom, followed by the components the install page lists: the Windows 11 SDK and the C++ build tools for x64 and ARM64.winget install --id Swift.Toolchain -e --source wingetinstalls Swift itself.
On every system the last step is the same: open a new terminal and run swift --version.
Checkpoint
Check: Swift on Linux and Windows
Choose the install that fits what you build
Three questions decide most of the choice: your computer, whether you will build apps for Apple devices, and whether you need more than one Swift version. Answer them in the table below, and it marks the installs that fit:
Answer the questions above: the table then marks what fits your case and says why the rest does not.
| Install | Apple app projects | Several Swift versions | Editor and debugger |
|---|---|---|---|
| Xcode 27 Runs on: macOS Tahoe 26.6 or later | Good the SDKs of every Apple platform, and xcodebuild | Mixed one compiler per Xcode release: Xcode 27 has Swift 6.4 | Good its own editor and debugger |
| Command Line Tools Runs on: macOS | Poor the macOS SDK only, and no xcodebuild | Poor one version of the package installed at a time | Mixed lldb and sourcekit-lsp, but no editor |
| swiftly on a Mac Runs on: macOS | Poor packages and tools; app projects still need Xcode | Good releases and snapshots side by side; swiftly use switches | Mixed SourceKit-LSP included; bring your own editor |
| swiftly on Linux Runs on: Linux | Poor no Apple SDKs on Linux | Good releases and snapshots side by side; swiftly use switches | Mixed SourceKit-LSP included; bring your own editor |
| winget on Windows Runs on: Windows | Poor no Apple SDKs on Windows | Mixed the current release; older ones as installers on swift.org | Mixed SourceKit-LSP included; bring your own editor |
How the answers decide
- “Which computer will you write Swift on?” A Mac: rules out swiftly on Linux and winget on Windows. These two install Swift on Linux and on Windows.
- “Which computer will you write Swift on?” A Linux computer: rules out Xcode 27, Command Line Tools, swiftly on a Mac and winget on Windows. Xcode, the Command Line Tools and the Mac installer of swiftly run only on macOS, and winget is the package manager of Windows.
- “Which computer will you write Swift on?” A Windows computer: rules out Xcode 27, Command Line Tools, swiftly on a Mac and swiftly on Linux. Xcode and the Command Line Tools are macOS software, and swiftly runs on macOS and Linux.
- “Will you build apps for iPhone, iPad or Mac?” Yes, apps for Apple devices: rules out Command Line Tools, swiftly on a Mac, swiftly on Linux and winget on Windows. App projects for Apple devices are built with Xcode, which has the SDKs of every Apple platform and xcodebuild; on Linux or Windows there is no way to build them.
- “Do you need more than one Swift version on this computer?” Yes, several versions: rules out Command Line Tools. Only one version of the Command Line Tools can be installed on a Mac at a time.
- “Do you need more than one Swift version on this computer?” Yes, several versions: adds a caveat to Xcode 27 and winget on Windows. Each Xcode release, and each Windows installer, holds one Swift release, so another version means another install; swiftly keeps several side by side.
In short: on a Mac, Xcode for app projects and the Command Line Tools or swiftly for everything else, with swiftly when you need several versions; on Linux, swiftly or a container image; on Windows, winget. Nothing in the first modules of this track needs more than one of them. Later needs can change the answer: Embedded Swift and WebAssembly come with the toolchains of swift.org, DocC with those toolchains or with Xcode, and app projects need Xcode. Either can be added later, beside what you install now.
Checkpoint
Check: Choosing an install
Ask the toolchain which Swift you are running
Installed is not the same as in use. A shell runs the first swift on its path, an editor may be set to another
toolchain, and Xcode runs its own. The only reliable answer comes from the compiler. This doctor program reports,
through #if conditions decided at compile time, which compiler built it, in which language mode, for which system, and
which libraries the build can import:
// doctor.swift: which compiler builds this file, in which language mode,
// for which system, and which libraries that build can import.
#if compiler(>=6.5)
print("compiler: Swift 6.5 or newer")
#elseif compiler(>=6.4)
print("compiler: Swift 6.4")
#elseif compiler(>=6.3)
print("compiler: Swift 6.3")
#else
print("compiler: older than Swift 6.3")
#endif
#if swift(>=6)
print("language mode: Swift 6")
#else
print("language mode: Swift 5 or older")
#endif
#if os(macOS)
print("system: macOS")
#elseif os(Linux)
print("system: Linux")
#elseif os(Windows)
print("system: Windows")
#else
print("system: another platform")
#endif
#if canImport(Foundation)
print("Foundation: can be imported")
#else
print("Foundation: not found by this build")
#endif
#if canImport(Testing)
print("Swift Testing: can be imported")
#else
print("Swift Testing: not found by this build")
#endif
#if canImport(XCTest)
print("XCTest: can be imported")
#else
print("XCTest: not found by this build")
#endif Here it is three times, run at once by swift, compiled with swiftc in the Swift 6 language mode, and compiled again
with one more search path:
from session import run, version
# The same file three ways: run at once by swift, compiled in the Swift 6 language mode, and compiled once more with
# the folder of the Command Line Tools' testing framework added to the compiler's search path (-F).
version()
run("""
swift doctor.swift
swiftc -language-mode 6 doctor.swift -o doctor
./doctor
swiftc -language-mode 6 -F /Library/Developer/CommandLineTools/Library/Developer/Frameworks doctor.swift -o doctor
./doctor
""") Output
# Apple Swift version 6.4 (swiftlang-6.4.0.34.1) $ swift doctor.swift compiler: Swift 6.4 language mode: Swift 5 or older system: macOS Foundation: can be imported Swift Testing: not found by this build XCTest: not found by this build $ swiftc -language-mode 6 doctor.swift -o doctor $ ./doctor compiler: Swift 6.4 language mode: Swift 6 system: macOS Foundation: can be imported Swift Testing: not found by this build XCTest: not found by this build $ swiftc -language-mode 6 -F /Library/Developer/CommandLineTools/Library/Developer/Frameworks doctor.swift -o doctor $ ./doctor compiler: Swift 6.4 language mode: Swift 6 system: macOS Foundation: can be imported Swift Testing: can be imported XCTest: not found by this build
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 doctor_session.py
Two lines change. swift doctor.swift reports the Swift 5 language mode: both swift and swiftc use it unless you
ask for another, which is why this track adds -language-mode 6 to every build of a single file. And Swift Testing is
found only by the last build, whose -F option adds the frameworks folder of the Command Line Tools to the compiler’s
search path. A plain swiftc does not search there; swift test, which the testing lessons use, does it for you.
XCTest is found by none of them, because these tools do not contain it.
Comparing outputs before comparing compilers
When your output differs from a session on these pages, run swift --version first, in the same terminal. A
different first line, such as Swift 6.3 instead of 6.4, explains more differences than any bug in the code.
Checkpoint
Check: Which Swift a build uses
An editor that understands Swift
Xcode understands Swift by itself. Other editors use SourceKit-LSP: The language server that comes with Swift toolchains and Xcode. Editors talk to it through the Language Server Protocol to show errors as you type, completions and definitions., the language server
that comes with Swift toolchains and with Xcode: the editor asks it, through the Language Server Protocol, for errors,
completions and definitions. The Swift extension for VS Code is published on the VS Code Marketplace and, since Swift
6.4, on the Open VSX Registry, so editors built on VS Code, such as Cursor, can install it too. Neovim, Emacs and other
editors that speak the protocol can start sourcekit-lsp directly. Step through what happens while you open a file and
type:
The drawing shows the whole scene; its 7 steps are listed below.
Every step as text
- You open a file. The editor starts the sourcekit-lsp program of the toolchain it is set to use and tells it which file you opened. They talk through the Language Server Protocol, so any editor that speaks it can work with Swift.
- How is it built?. SourceKit-LSP finds out how the file is compiled, from Package.swift for a package or from a compile_commands.json file that another build system writes.
- Checking the file. With those settings it has the toolchain's compiler check the file, so you see type errors before you build.
- Errors as you type. SourceKit-LSP hands the diagnostics on, and the editor underlines them. Each change you type starts the round again.
- Completion. When you ask for completion, the editor sends the position of the cursor, and SourceKit-LSP answers with the names that fit there.
- Across files and modules. Jumping to a definition in another file or module needs an index of the whole package. Since Swift 6.1, SourceKit-LSP builds that index in the background when a package is opened, so these features start to work once the first indexing is done.
- Same toolchain everywhere. The editor's SourceKit-LSP comes from one toolchain, so pick the same one your terminal uses. In VS Code the command "Swift: Select Toolchain…" does that.
The last two steps cause most editor trouble. Jumping between files and modules needs an index of the whole package, which SourceKit-LSP builds in the background when you open a package, so those features start to work once the first indexing has finished. The other cause is a second toolchain, so point the editor at the same one as your terminal: in VS Code, the command “Swift: Select Toolchain…” does it, and the doctor program above tells you which toolchain a build uses.
Version note
Background indexing is on by default since Swift 6.1. With a Swift 6.0 toolchain, cross-file features waited for a
swift build, which is why older guides tell you to build first.
Checkpoint
Check: Editors and SourceKit-LSP
Practise
Practice here picks the idea you have shown least, gets harder as you answer well, and brings back what you miss. Then
run the doctor on your own computer: save doctor.swift, type the commands of the session above, and compare the six
lines with the recorded ones. On a Linux computer the system line says Linux and, with a swift.org toolchain, other
lines may change too; that is the point of asking.
Practice that adapts to you
Practise this lesson
10 questions about 5 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.
Interview questions
Warm-up: how do you tell which Swift compiler a terminal or an editor really uses?
Ask the compiler, not the installer. In the terminal, swift --version prints the compiler’s version and build, for
example “Apple Swift version 6.4 (swiftlang-6.4.0.34.1 …)”, and the target it builds for. which -a swift lists every
swift on the path in the order the shell tries them, and on a Mac xcode-select -p shows which developer folder
/usr/bin/swift uses, Xcode or the Command Line Tools. An editor can run another toolchain than the terminal, so check
its setting too, such as “Swift: Select Toolchain…” in VS Code. A program can also report it from inside, with
#if compiler(>=6.4) and #if swift(>=6), which tell the compiler version and the language mode apart.
Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.
-
Fresher to mid
A package builds on every laptop of the team, but on the CI machine the build fails with "unknown attribute 'diagnose'". How do you find the cause, fix it, and stop it from happening again?
-
Fresher to mid
A teammate with only the Command Line Tools on their Mac cannot build the tests of an older package: the compiler reports that there is no module XCTest. Explain the cause and give two ways to fix it, with what each costs.
Key takeaways
- On a Mac, Xcode 27 brings Swift 6.4 with every Apple SDK and is needed for app projects; the Command Line Tools are the smaller install for the language, and swiftly keeps several swift.org toolchains side by side.
- On Linux, swiftly or the official
swiftcontainer images install Swift; on Windows, winget installs Visual Studio’s build tools first and Swift second. - The Command Line Tools hold the compiler, SwiftPM, swift-format, SourceKit-LSP, LLDB and Swift Testing, but no XCTest and no DocC.
swift --version,which -a swiftand a program that uses#if compiler()and#if swift()tell you which compiler and language mode a build really uses; a bareswiftorswiftcuses the Swift 5 mode.- Editors other than Xcode understand Swift through SourceKit-LSP, which should come from the same toolchain as your terminal and, since Swift 6.1, indexes a package in the background for cross-file features.
Terms in this lesson
- Command Line Tools
- Apple's package of the command-line compilers and the macOS SDK that ship with Xcode, without Xcode itself. xcode-select --install puts it in /Library/Developer/CommandLineTools.
- SourceKit-LSP
- The language server that comes with Swift toolchains and Xcode. Editors talk to it through the Language Server Protocol to show errors as you type, completions and definitions.
- swiftly
- The command-line tool of swift.org that installs Swift toolchains on macOS and Linux, keeps several side by side and switches between them with swiftly use.
- toolchain
- The programs of one Swift release that turn source code into running programs: the compiler, the standard library, the Swift Package Manager and tools such as LLDB and SourceKit-LSP.
References
- Install Swift (Swift.org)
- Install Swift on macOS (Swift.org)
- Install Swift on Linux (Swift.org)
- Install Swift on Windows (Swift.org)
- Xcode support: minimum requirements and supported SDKs (Apple)
- Installing the command-line tools (Apple)
- swiftly, a Swift toolchain installer and manager (The Swift Project (swiftlang))
- The swift Docker Official Image (Docker Hub (maintained by the Swift community))
- About Swift (platform support) (Swift.org)
- Swift-DocC (The Swift Project (swiftlang))
- SourceKit-LSP (The Swift Project (swiftlang))
- SourceKit-LSP documentation: Background Indexing (on by default since Swift 6.1) (The Swift Project (swiftlang))
- Getting started with Swift in VS Code (Swift.org)
- Swift 6.4 Released (the VS Code extension on Open VSX) (Swift.org)
- Language Server Protocol Specification 3.17 (Microsoft)
- The Swift Programming Language (6.4): Statements, Conditional Compilation Block (Swift.org)
- Swift Playground (Apple)
Report a problem with this lesson
Kept only in this browser. Your Learn progress