Swift 6.1: All the New Features in Detail

Published on Β· Updated Β· 9 min

Wlad
Wlad
Founder & Swift Tech Lead

Six months after the major release of Swift 6.0, Apple delivers Swift 6.1 with Xcode 16.3. A lighter update on the surface, but one that brings much-anticipated quality-of-life improvements for the community. Here's a complete overview.

What really changes

Swift 6.1 is not a revolution. It's a consolidation release that addresses daily friction points: less boilerplate in concurrency, more syntactic flexibility, and diagnostic tools finally up to par. The kind of update you appreciate in day-to-day work.

Here are the main new features:

  • Extension of the nonisolated keyword to types and extensions

  • Trailing commas support everywhere

  • Automatic type inference for TaskGroup

  • Package Traits for conditional compilation

  • New @implementation attribute for Objective-C interop

  • Swift Testing improvements

  • Fine-grained compiler diagnostic control

nonisolated extended to types and extensions

Until Swift 6.0, nonisolated only applied to individual properties and functions. Problem: when you have a type marked @MainActor but several members don't need isolation, the code becomes verbose.

Swift 6.1 now allows marking an entire type or extension as nonisolated.

Before Swift 6.1

With Swift 6.1

This approach is particularly useful when implementing protocols that don't need isolation on a type that has one by default.

Trailing commas: finally everywhere

Proposal SE-0439 extends trailing comma support to virtually all language contexts. A long-standing community request, particularly useful for refactoring and cleaner Git diffs.

Where it works now

Why it's useful

Imagine you need to temporarily comment out the last parameter of a call:

Without a trailing comma, commenting the last line would have caused a syntax error.

TaskGroup: automatic type inference

TaskGroup previously required explicitly specifying the return type of child tasks. Swift 6.1 infers this type automatically from the first added task.

Before Swift 6.1

With Swift 6.1

The compiler infers the User? type from the return of fetchUser(id:). Less boilerplate, same result.

Package Traits: conditional compilation for SwiftPM

Package Traits allow defining optional features in your Swift packages. Particularly useful for Embedded Swift, WebAssembly, or any context where certain dependencies aren't available.

Defining traits in Package.swift

Using traits in code

Enabling a trait on the consumer side

Objective-C interoperability: @implementation

The new @implementation attribute allows providing a Swift implementation for a declaration imported from Objective-C. Ideal for progressively migrating legacy code.

Use case: replacing an Objective-C @implementation

If you have an Objective-C header:

You can now provide the implementation in Swift:

This allows removing the corresponding .m file while keeping the Objective-C interface intact for the rest of the codebase.

Swift Testing: new capabilities

Swift Testing gains flexibility with improvements to test macros.

Swift Testing also introduces TestScoping to customize test execution context (setup/teardown). The API evolved between Swift 6.1 and 6.2 β€” for implementation details, see ST-0007.

Retrieving the captured error

The #expect(throws:) and #require(throws:) macros now return the captured error:

Fine-grained diagnostic control

SE-0443 introduces granular control over compiler warnings and errors.

Enabling diagnostic group display

In Xcode Build Settings, add -print-diagnostic-groups to Swift Compiler Custom Flags. Messages will then show their category:

Controlling warnings via compiler flags

Swift uses -Wwarning to keep a diagnostic as a warning, and -Werror followed by the group name (with a space, not =) to treat it as an error:

Migrating from Swift 6.0

Upgrading to Swift 6.1 is generally seamless. A few points to watch:

Imported member visibility

Swift 6.1 introduces an optional stricter visibility mode for imports. If you had transitive imports (accessing an API through an import in another file), you may need to add explicit imports.

To enable this behavior:

Recommended verification

Going further

Swift 6.1 sets the stage for Swift 6.2, which will bring more significant changes to concurrency. In the meantime, these quality-of-life improvements are worth adopting now.

Official resources