Profile
Back to NewsBack
Hacker News 9 min
Reader Mode
Swift 6.4 Released

Swift 6.4 Released

3 hours ago

Swift 6.4 Released

The Swift logo with the text Swift 6.4 The Swift logo with the text Swift 6.4

Swift 6.4 is now available. Swift aims to be a great choice across the stack, from apps and servers to systems code, embedded devices, and the browser. This release deepens that support, and makes everyday code easier to write. Highlights include:

  • Swift Build is now the default in Swift Package Manager, so your projects build the same way on Linux, macOS, and Windows.
  • Subprocess reaches 1.0, a stable, cross-platform way to run and interact with other programs from Swift, from command-line tools to streaming processes.
  • Interoperability reaches further, with Swift’s Span now bridging directly with C++20’s std::span, and Swift/Java interop extending its async and callback support.
  • Swift runs faster in the browser, with WebAssembly bridging through JavaScriptKit up to 40 times faster, and the Wasm SDK available directly from Swift.org.
  • Embedded Swift grows more capable, with support for existential types and richer error handling for microcontroller-class targets.
  • Performance improves while maintaining memory safety, with new array types that hold non-copyable elements without copy-on-write overhead, and the new Iterable protocol for iterating without copies.

There’s so much more. Read on for a detailed guide to the new changes, or see the Swift Evolution dashboard for the full list of proposals in Swift 6.4.

Simpler and clearer code

Swift 6.4 streamlines your day-to-day programming to make your code simpler and clearer.

  • More natural optional some and any types. When writing an optional some or any type, you no longer have to wrap the type in parentheses. Instead of (some Rocket)?, you can simply write some Rocket? (SE-0521).
  • Source-level control over compiler warnings. When you need to control the behavior of warnings in your project, such as suppressing warnings or promoting them to errors, you can now define the warning behavior directly in your code using the new @diagnose attribute (SE-0522).
  • Clarify which API to use when multiple libraries conflict. When multiple modules define the same API name that you want to reference, you can specify which module you meant to use through module selectors. If your app imports two modules that both provide a type CommonThing, using the :: selector lets you clearly specify which of those you intend (SE-0491).
  • Call async functions in a defer block. Any asynchronous code you write in a defer block is awaited and runs to completion before it exits (SE-0493).
  • Ensure that necessary cleanup work isn’t cancelled. You can run a closure that’s shielded from the enclosing task’s cancellation through the withTaskCancellationShield API (SE-0504).

You can combine asynchronous calls in defer blocks and cancellation shields to make sure that cleanup work always happens, no matter how the function returns:

func processFile(at url: URL) async throws {
    let handle = try FileHandle(forReadingFrom: url)

    defer {
        // flushMetrics is a network call, so it can suspend after cancellation
        // is requested; the shield ensures it runs to completion and isn't
        // included in cancellation.
        await withTaskCancellationShield {
            await flushMetrics(for: url)
            try? handle.close()
        }
    }

    try await processContents(of: handle)
}

Richer core library APIs

Improvements to Foundation and the standard library make it easier to use modern APIs with existing types.

For example, ProgressManager added API to provide async/await support (SF-0023), and @Observable types now have fine-grained and continuous change notifications (SE-0506).

The Subprocess library — originally introduced as SF-0007 and released as an initial 0.1 version in 2025 — has reached 1.0. It provides a cross-platform package to run and interact with subprocesses, built from the ground up using Swift concurrency. The following example, from Getting Started with Subprocess, illustrates running a process and capturing its output.

let result = try await Subprocess.run(
  .name("ls"),
  arguments: ["-la"],
  output: .string(limit: 4096)
)
print(result.standardOutput)

Swift 6.4 makes it easier to migrate existing projects to use Swift Testing. You can now safely use XCTAssert in Swift Testing tests or #expect within XCTests (ST-0021), and customize the values shown in failed expectations using the CustomTestReflectable protocol (ST-0022). swift test lets you repeat test cases to focus and save time (ST-0024) and record attachments that conform to the Transferable protocol on Apple platforms (ST-0023).

Swift now has a documentation site, and the documentation content for the standard library is now open source.

Faster builds, clearer debugging, broader IDE support

Swift 6.4 brings a range of tooling improvements that make everyday development smoother, from debugging and building to editor support:

  • More robust debugging. Swift 6.4 completes a multi-release overhaul of how the compiler tracks Swift modules in debug info — LLDB now imports modules through precise dependency tracking instead of ambiguous by-name lookups. Debug builds on Linux and Windows, and dSYM bundles on Darwin, shrink significantly since binary Swift modules are no longer embedded in them. Read the recent blog post Module Tracking in Swift Debug Info for a dive into the details.
  • Unified build system across IDEs. Swift Package Manager (SwiftPM) now uses Swift Build as its default build platform, and includes Software Bill of Materials (SBOM) Generation for Swift Package Manager (SE-0509), providing support for generating SBOM documents in either SPDX or CycloneDX format. Read more about SwiftPM’s updates in the SwiftPM 6.4 release notes, and learn how to generate an SBOM at Generating Software Bill of Materials (SBOM).
  • Broader IDE support for Swift. The VS Code extension for Swift is now available on the Open VSX Registry, so it works not only in VS Code, but also Cursor, Antigravity, Kiro, and other development tools. It also now includes integration with Swiftly, making it easier to select and use different versions of Swift toolchains with your project.

Deeper interoperability and platform support

Swift’s interoperability expands its reach across more of the stack: from systems-level C++ to Android’s Java runtime, and from WebAssembly (Wasm) in the browser to Embedded Swift on microcontrollers.

Language interoperability goes deeper this release.

  • C: Pair @c with @implementation to use a Swift function to provide the implementation for a C header with no separate C declaration. Without @implementation, the compiler emits the declaration into the generated header. Either way, @c functions can get safe wrappers, such as a function that uses Span in place of a raw pointer-and-count pair.
  • C++: Swift 6.4 bridges C++20’s std::span with Swift’s Span, so you can pass a Span to a C++ API that expects a std::span, and receive a std::span back as a Span, without writing manual conversion code at the boundary.
  • Java: The Swift/Java interop project, which lets you call Swift from Java and Kotlin, extends its support for calling async and throwing functions to protocol and callback wrappers, adds automatic Runnable mapping for closures, variadic parameter import, and support for Java record types.

Swift’s platform support deepens as well.

WebAssembly

JavaScriptKit has better performance when bridging to Wasm in Swift 6.4, with safe bridging up to 40 times faster than earlier dynamic bridging. The Wasm SDK is available from the Install Swift page of Swift.org, so compiling Swift for the browser requires no extra setup beyond adding the SDK.

Foundation updates for Swift 6.4 improve FileManager support on WASI (the WebAssembly System Interface).

Android

Swift on Android continues to advance. This release of the Swift SDK for Android is built with the new LTS NDK 30, which provides Android availability attributes both in the Swift runtime libraries and for your Swift packages using the default NDK. Swift Build now supports Android in SwiftPM as well, removing the need for a post-install script.

Embedded Swift

The earlier post Embedded Swift Improvements Coming in Swift 6.4 covers Embedded Swift’s other improvements in this release in more depth, including generalized support for existential types (such as any Protocol), which lets you naturally express heterogeneous collections and throw and catch any Error.

Embedded Swift also gains a new EmbeddedRestrictions warning that you can enable across a whole target:

// Package.swift — enable EmbeddedRestrictions warnings for the target
.target(
    name: "FirmwareCore",
    swiftSettings: [
        .treatWarning("EmbeddedRestrictions", as: .warning)
    ]
)

Faster code that stays safe

Swift 6.4 makes it easier to avoid unnecessary copies of your data while staying memory-safe, extending earlier work on Span, non-copyable types, and InlineArray.

  • Work with values in memory without copying them. Borrow and mutate accessors let you read or update a Span or InlineArray through a property (SE-0507), non-copyable types can now conform to Equatable, Comparable, and Hashable, and new Ref and MutableRef types give you a first-class, storable container that lets you borrow or mutate one value at a time (SE-0519). Optionals of non-copyable types now work the same way, so you can inspect or update what’s inside an Optional without consuming it (SE-0532).
  • Build collections and heap-allocated values without unnecessary memory allocation. UniqueBox gives you a smart pointer that uniquely owns a heap value, including non-copyable values, without reference counting (SE-0517). RigidArray and UniqueArray store non-copyable elements without the copy-on-write allocations you would see when using Array. RigidArray provides a fixed-capacity buffer, and UniqueArray provides a buffer that grows dynamically (SE-0527). You can loop over elements and borrow them with the Iterable protocol, instead of copying each value, which extends beyond what the Sequence protocol supports (SE-0516).
  • Access raw memory safely, without using unsafe-annotated APIs. withTemporaryAllocation provides a scratch buffer that is automatically initialized and cleaned up (SE-0524). A new safe loading API lets RawSpan and its variants load and store bytes safely, replacing the unsafe-flagged functions (SE-0525).

Thank you

Swift 6.4 reflects the contributions of many people across the Swift community, through code, proposals, forum discussions, and feedback. The community’s thoughts and real-world experience provide invaluable insights and motivation!

If you’d like to get involved in what comes next, the Swift Forums are a great place to start.

Get started with Swift 6.4

Try out Swift 6.4 today by following the instructions on the Install Swift page, or download the new 6.4 toolchain with Swiftly.


Authors

Joe Heck works on Swift as part of the Open Source Program Office at Apple.
Holly Borla is a member of the Swift Core Team and Language Steering Group, and the engineering manager of the Swift language team at Apple.

Continue Reading

Chat with me