Swift Tooling: Windows Edition
Productivity on every platform - a deep dive on the ways we're writing Swift code on Windows, and improving the developer experience along the way.
Swift on Windows is production ready, today. We’ve talked before about how we run Swift code on Windows, but we haven’t talked about how we write Swift code on Windows. Windows is already a mature development environment for authoring Swift code, and it’s only getting better. Here we will go over the state of the Swift ecosystem and tooling support on Windows, and discuss our plans to continue to improve the developer experience for Swift devs working on Windows.
The Swift Developer Experience:
Visual Studio Code (hereafter “VS Code”) is the development environment of choice for writing Swift code on Windows. The Swift Server Workgroup publishes an official Swift extension for VS Code, which serves as the primary integration point for a great deal of Swift tooling. All the IDE features you would expect are available: building and debugging with breakpoints; running and debugging tests; code navigation, autocomplete, and hover documentation; inline error reporting; and more. In addition to the first-party Swift extension, there are a plethora of other ways to extend VS Code to enhance the development experience. For example, GitHub’s AI-powered Copilot extension works great with Swift!
When opening a Swift project for the first time in VS Code, the Swift extension kicks into gear and starts setting up your development environment. The extension generates launch configurations, which enable you to build and debug at the press of a button (Ctrl+Shift+b
to build; F5
to debug). Dependencies are discovered and checked out and, after the first build, the project’s tests are enumerated in the VS Code test explorer, providing a convenient way to run and debug tests. This initial build also generates a symbol index, which powers language services like “go to definition” and refactoring.
All of this comes together to provide a first-class development experience for writing Swift programs on Windows. The Swift ecosystem and tooling on Windows is productive and ready for industry use.
Editing code:
We’ve come a long way from the days of teletypes and ed
! VS Code is extensible with language-specific editor services via the language server protocol. The Swift extension provides this functionality via sourcekit-lsp
, a language server implementation for Swift that is built on the same sourcekitd
library used by Xcode. Code completion simplifies API discovery and avoids context switches to pore over documentation. Code navigation allows you to breeze through the codebase and spend less time scrolling through the file explorer, by enabling you to jump straight to the location where a symbol is defined, or finding all references of a given symbol in the codebase. Errors and warnings are displayed inline in the editor, so there’s no need to visually parse line numbers out of compiler errors.
Programmers all have their own opinions about code style, but most will agree that codebase consistency is more important than any particular style. Automated formatting tools trivialize this style consistency: swift-format
will keep your codebase nice and clean. This tool is integrated into sourcekit-lsp
, and is also available as a standalone CLI tool.
Building and testing code:
The Swift toolchain includes the Swift Package Manager (SPM), which is the primary command line application for interacting with the Swift compiler. It can build your project, run your tests, manage your dependencies, and more. Many of the nice VS Code integrations outlined above are enabled by this tool, which is supported on Windows.
While SPM covers the 99% use-case, sometimes you need a little more control over a project’s build. For those cases, CMake can be used to build Swift projects with meticulous control. CMake supports integrating external tools into a project’s build, like calling into swift-winrt
to generate WinRT bindings. It also enables you to limit the visibility of symbols in built dynamic libraries, which prevents running into the Windows limit of 64k exported symbols per DLL in large projects. CMake already supports building Swift projects, and the upcoming 3.29 release will bring further improvements, including support for language servers like sourcekit-lsp
.
You’re also not limited to building just for Windows x64: building for ARM64 is supported, which is particularly useful for cross platform development on a Mac with Windows running in Parallels. Official ARM64 toolchain builds are still in the works, but preview builds are available today on The Browser Company’s fork of swift-build
. Cross-compilation in either direction is supported by both SPM and CMake.
Testing with XCTest is supported with both build systems. When using SPM to build your project, the Swift extension discovers tests in your project and populates VS Code’s test explorer. Testing with CMake requires a bit more manual effort to set up, but with a bit of work it’s possible to programmatically generate test harnesses and register the tests with CTest, CMake's test runner. Once everything is defined in CMake terms, the CMake Tools VS Code extension provides test explorer integration.
Debugging:
Debugging Swift code on Windows is easy and familiar. The Swift toolchain ships with LLDB, which implements Microsoft’s Debug Adapter Protocol (DAP), enabling seamless integration with VS Code. Command line debugging is also available, for those who feel more at home in a terminal. The toolchain also includes swift-inspect
, a tool which enables you to gather information about a running Swift process, although there’s still work to do to enable concurrency inspection on Windows.
Debugging compiled binaries requires generating debug information, which can identify the source location of symbols and provide other useful data to the debugger about the program that would otherwise have been lost during compilation. DWARF is the preferred debug information format for Swift, as it enables rich debugging with LLDB, but Swift on Windows can also generate partial debug information in the PDB format to integrate with Windows first-party debugging tools. PDBs don’t reliably enable runtime inspection of Swift variables, but they provide enhanced debugging of code that interfaces with Windows system APIs. Generation of PDB files is supported when building Swift on Windows with both SPM and CMake.
A benefit of developing on Windows is access to the suite of first-party debugging tools published by Microsoft. WinDBG is a general purpose debugger with decades of development behind it, and is particularly useful for debugging Swift programs which interact with Windows system libraries. Because of the PDB files generated alongside Swift programs, stacktraces which cross language interop boundaries are fully symbolicated. For tracking down performance issues, Windows Performance Analyzer (WPA) provides detailed breakdowns of performance characteristics and resource usage during a run of the application.
Tooling survey:
The official Swift plugin for VS Code (GitHub, Swift blog) provides integration points for building, formatting and linting, debugging, testing, language services, and more. Windows-specific issues are tracked here.
sourcekit-lsp
(GitHub) provides language services for Swift; like goto definition, autocomplete, refactoring, and more. It’s built on top of sourcekit, the language services library which powers Xcode, and is distributed as part of the Swift toolchain.swift-format
(GitHub) if the official Swift code formatter and is distributed as part of the Swift toolchain.swift-inspect
(GitHub) enables inspection of a live Swift process, like enumeration of live array objects or metadata allocations. Concurrency inspection is not yet enabled on Windows. This tool is distributed as part of the Swift toolchain.Swift Package Manager (GitHub) is the official Swift packaging tool. SPM provides entry points for building and testing projects, and will manage your project’s dependencies.
CMake (GitLab) is a powerful build tool with finer control over project build, although some manual configuration is required.
VS Code CMake Tools (GitHub) provides editor integration with CMake projects, such as test explorer support, building and debugging entry points, build tool configuration, and more.
lldb (GitHub, Swift.org) is LLVM’s debugger, extended to support Swift. It implements the Debug Adapter Protocol (DAP), which enables debugging straight from VS Code.
WinDbg (learn.microsoft.com) is a first-party Windows debugger, and is great for debugging Swift code that interacts with system libraries.
Windows Performance Analyzer (WPA) (learn.microsoft.com) provides event tracing and resource usage characteristics of the execution of a program on Windows. Great for finding performance bottlenecks in Swift applications.
Process Monitor (learn.microsoft.com) traces file system and registry access of an application, and general process/thread activity.
It’s Your Turn:
We hope you’ll agree that developing Swift on Windows is productive and fun. If you’ve been curious about writing Swift on Windows, there’s never been a better time to start. All you need to do is grab a Swift toolchain release and install VS Code with the Swift extension, and you’re ready to start coding! If you want to try out the latest features, you can grab a bleeding edge toolchain from The Browser Company’s swift-build releases, with the caveat that these toolchain releases may be less stable.
If you run into any problems or have suggestions, please file an issue in any of the repositories linked above (PRs are welcome too!) There’s still a lot of ways to make the developer experience even better. Let’s work together to make Swift on Windows the best it can be!
We’ll see you on the internet,
Jeremy
You write: “All you need to do is grab a Swift toolchain release and install VS Code with the Swift extension, and you’re ready to start coding!”
Is Visual Studio not required anymore? I recall you had to install it to get some required libraries in place. Great news if that’s not the case anymore!
Will Swift be able to create an Android application?