apple/swift-system: Swift's Home for System Calls, With No Cross-Platform Abstraction
Low-level system calls and types for Swift. Swift System Swift System provides idiomatic interfaces to system calls and low-level currency types.
At a glance
- What is it?
- Swift System wraps open, read, write and path handling in typed Swift APIs, but it deliberately keeps platform differences visible. Here is what it does, how to add it, and where it stops being the right tool.
- Who is it for?
- Adopt Swift System if you are writing a library or application that needs typed file descriptors, FilePath manipulation, or POSIX calls and you are willing to keep platform-specific code behind #if os() conditionals. Skip it if what you actually want is one uniform file API across macOS, Linux and Windows, because the README states plainly that eliminating those conditionals is not a design goal.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Swift, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Swift System Is For, and Who It Is For
Swift System provides idiomatic Swift interfaces to system calls and low-level currency types. The README states the vision directly: System should act as the single home for low-level system interfaces for all supported Swift platforms. The immediate goal named there is narrower and more useful for judging fit: simplify building cross-platform libraries and applications such as SwiftNIO and SwiftPM.
That framing matters because the package is not aimed at application developers who want a friendly file API. It is aimed at people writing the layer underneath that, the code that has to open a file descriptor, read and write bytes, and construct paths without going through Foundation or Glibc or WinSDK by hand. If you are writing an HTTP server, a package manager, or a runtime, you are the intended audience. If you are writing an app that reads a config file, you probably are not.
No Cross-Platform Abstractions Is the Design, Not a Gap
The most important sentence in the README is a refusal. Swift System is not a cross-platform library. It provides a separate set of APIs and behaviors on every supported platform, closely reflecting the underlying OS interfaces, and a single import pulls in the native platform interfaces for the targeted OS.
The README is explicit that eliminating the need for #if os() conditionals is not a design goal. The stated goal is to make it safer and more expressive to fill out the platform-specific parts. This is a real trade-off and worth stating plainly: adopting Swift System does not reduce the number of platform branches in your code. It changes what sits inside those branches from raw C calls to typed Swift calls.
The README does hold out one softening principle. It says it is desirable to avoid unnecessary differences, giving the example that when two operating systems share the same C name for a system call, Swift System should ideally expose them under the same Swift name, and calls this an obvious expectation for interfaces implementing an industry standard such as POSIX. So the surface is aligned where POSIX aligns it, and divergent where the platforms genuinely diverge.
Adding SystemPackage to a SwiftPM Project
The package is consumed through Swift Package Manager. The README shows the dependency line to add to Package.swift, pinned with a from: version requirement. Version 1.8.0 is the release the README uses in its example; the repository's most recent release listed is 1.8.1.
.package(url: "https://github.com/apple/swift-system", from: "1.8.0"),Then the product is attached to a target. The README's example names the product SystemPackage and the package swift-system, which is how SwiftPM resolves the dependency declared above.
let package = Package(
dependencies: [
.package(url: "https://github.com/apple/swift-system", from: "1.8.0"),
],
targets: [
.target(name: "MyTarget", dependencies: [
.product(name: "SystemPackage", package: "swift-system"),
]),
]
)The README's usage example is the shortest honest demonstration of the API shape. It builds a FilePath from a string literal, opens a FileDescriptor with writeOnly access, append and create options, and ownerReadWrite permissions, then writes a UTF-8 string through the descriptor and closes it with closeAfter.
import SystemPackage
let message: String = "Hello, world!" + "\n"
let path: FilePath = "/tmp/log"
let fd = try FileDescriptor.open(
path, .writeOnly, options: [.append, .create], permissions: .ownerReadWrite)
try fd.closeAfter {
_ = try fd.writeAll(message.utf8)
}What you should see is the line appended to /tmp/log. Two details are worth noticing because they are the reason to use this over raw calls. FilePath is a distinct type, not a String, so path construction and manipulation are typed. And closeAfter scopes the descriptor to a closure, which removes the class of bug where an early return or a thrown error leaves a descriptor open. The README does not document what happens if the closure body throws and closeAfter itself fails; the API documentation is the place to check that.
Source Stability Differs by Platform, and Windows Is the Exception
The README carries a table of source stability by platform type. Darwin (macOS, iOS and similar) is Stable. POSIX (Linux, WASI and similar) is Stable. Windows is Unstable.
That distinction is not cosmetic. The README says version numbers follow Semantic Versioning, and that source-breaking changes to source-stable public API can only land in a new major version. But platforms that have not reached source stability may see source-breaking changes in a new minor version. So a Windows consumer can be broken by a 1.x to 1.y bump that a Linux consumer cannot.
The README also defines the public API precisely, which is unusually helpful. It consists of non-underscored declarations marked public in the SystemPackage module. Underscored means a leading underscore anywhere in the fully qualified name, and the README gives four examples: an underscored member, an underscored type, an underscored module, and an underscored initializer. Interfaces outside that set may change in any release, including patch releases. If you find yourself reaching for an underscored declaration, the README asks you to file a Feature Request rather than depend on it.
Toolchain Requirements Move, and Minor Releases Can Raise Them
The README publishes a mapping from package version to minimum Swift toolchain and Xcode release. Swift System 1.3.x needs Swift 5.8 or newer and Xcode 14.3 or newer. Versions 1.4.0 through 1.6.x need Swift 5.9 or newer and Xcode 15.0 or newer. Versions 1.7.0 through 1.8.x need Swift 6.1 or newer and Xcode 16.3 or newer.
This is an upgrade cost you should budget for. The README states the intent: the package wants to embrace Swift language and toolchain improvements relevant to its mandate, and from time to time new versions require clients to upgrade to a more recent toolchain. Patch releases will not increase the required toolchain version, but any minor release may. That is a stricter policy than many libraries follow, and it means a routine swift-system minor bump can force a compiler upgrade across your whole build.
One mitigating note is in the README: the package has no minimum deployment target. It requires a recent toolchain to build, but the code itself can run on any OS release that supports running Swift code. So the cost lands on your build machines and CI, not on your users' operating systems.
How Maintenance and Upgrades Are Actually Run
The repository keeps separate branches for each active minor version, listed in the README as release/1.3.0 through release/1.8.x, with 1.9.x marked unreleased. Changes must land on the branch corresponding to the earliest release they need to ship on, and are periodically propagated forward: release/1.7.0 to release/1.8.x to main. The README notes that this propagation currently requires manual work performed by project maintainers, and that contributors do not need to file standalone PRs for each release line.
For a consumer, the practical consequence is that a fix backported to an older line may take time to appear in newer lines, because the forward merge is a human step. If you are pinned to an older minor version, check the branch for that version rather than assuming main carries the fix.
The most recent release listed is 1.8.1 on 2026-08-14, and the last push to the repository was also on 2026-08-14. The repository is not archived. The README does not document a rollback procedure or a deprecation policy beyond the Semantic Versioning statement and the source stability table.
On licensing: the repository is Apache-2.0, and the README defers to LICENSE.txt for license information rather than restating terms. Apache-2.0 is a permissive licence with an explicit patent grant and a notice requirement; read LICENSE.txt and your own organisation's policy rather than relying on that summary.
When Swift System Is the Wrong Tool
The clearest failure case is a project whose actual requirement is one file API that behaves identically on macOS, Linux and Windows. Swift System will not give you that, and the README says so. You will still write the #if os() branches yourself, and now you will write them against a package that changes shape on Windows in minor releases. Foundation's file APIs, or a purpose-built portability layer, address a different problem than Swift System does.
The second case is a project that needs a stable ABI or a long-term support commitment. The toolchain policy means a minor release can require a newer Swift compiler, and the Windows source stability row means a minor release can break your code. Neither is a defect, but both are incompatible with a codebase that upgrades its compiler on a slow cadence.
The third case is a project that only ever targets one platform and only needs a handful of calls. Adding a dependency to wrap three system calls is not obviously better than calling them directly, and the package's value comes largely from being the shared home for this layer across SwiftNIO, SwiftPM and similar projects.
A real alternative in the same ecosystem is Foundation, which ships with the toolchain and covers file and path operations at a higher level. The difference in approach is the one the README draws: Foundation aims at a uniform API across platforms, while Swift System aims to reflect each platform's native interfaces closely and leave the uniformity to you. If your code is already written against Foundation and does not need file descriptors or raw path semantics, Swift System adds a dependency without removing work.
Editorial conclusion
Adopt Swift System if you are writing a library or application that needs typed file descriptors, FilePath manipulation, or POSIX calls and you are willing to keep platform-specific code behind #if os() conditionals. Skip it if what you actually want is one uniform file API across macOS, Linux and Windows, because the README states plainly that eliminating those conditionals is not a design goal. Before you add the dependency, check two things in the repository: the toolchain table, since 1.7.0 through 1.8.x require Swift 6.1 and Xcode 16.3 or newer, and the source stability table, since Windows is listed as unstable and may see source-breaking changes in a minor release.
Frequently asked questions
What is apple/swift-system?
It is a Swift package that provides idiomatic interfaces to system calls and low-level currency types, with the stated vision of being the single home for low-level system interfaces on all supported Swift platforms. Its public API lives in the SystemPackage module.
Does swift-system give me one cross-platform file API?
No. The README states that Swift System is not a cross-platform library and that eliminating the need for #if os() conditionals is not a design goal. It exposes a separate set of APIs and behaviors per platform, reflecting the underlying OS interfaces.
Which Swift toolchain does swift-system 1.8.x require?
The README's toolchain table maps swift-system 1.7.0 through 1.8.x to Swift 6.1 or newer and Xcode 16.3 or newer. Patch releases will not raise the requirement, but a minor release may.
Is swift-system stable on Windows?
No. The source stability table lists Darwin and POSIX as Stable and Windows as Unstable, and the README notes that platforms which have not reached source stability may see source-breaking changes in a new minor version.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/apple-swift-system)