Approachable Concurrency in Swift Packages

Xcode 26 ships with Swift 6.2 and enables Approachable Concurrency. How do you adopt it in existing projects and in Swift Packages?

What is Approachable Concurrency?

In Swift 6.2 Apple is introducing a new more approachable way to use Swift Concurrency. It starts with the assumption that you start by running your app’s code on the main thread and only move work to a background thread when needed.

I highly recommend watching the session video WWDC25 Embracing Swift concurrency and/or reading the Swift Evolution proposals to learn more:

Enabling in Xcode 26

Creating a new project with Xcode 26 enables MainActor default isolation and approachable concurrency by default. For an existing project you opt-in by changing the build settings for a target:

Swift compiler concurrency build setting with approachable concurrency yes, default actor isolation MainActor, and strict concurrency complete

Enabling Approachable Concurrency enables a couple of extra upcoming features:

Swift compiler

The Infer Isolated Conformances setting enables SE-0470 (upcoming feature flag InferIsolatedConformances). The nonIsolated(nonsending) By Default setting enables SE-0461 (upcoming feature flag NonisolatedNonsendingByDefault).

The other concurrency features are enabled with Swift 6.

Using in a Swift Package

You can apply the build settings for approachable concurrency and default actor isolation to one or more targets in your Swift Package. You need to update the swift tools version to 6.2 (first line of Package.swift):

// swift-tools-version: 6.2

To set the Default Actor Isolation (SE-0466) for a target, there’s a new swiftSettings option:

.target(
  name: "MyFeature",
  swiftSettings: [
    .defaultIsolation(MainActor.self)
  ]
)

To enable approachable concurrency, add the upcoming feature flags for both SE-0461 and SE-0470:

.target(
  name: "MyFeature",
  swiftSettings: [
    .defaultIsolation(MainActor.self),
    .enableUpcomingFeature("NonisolatedNonsendingByDefault"),
    .enableUpcomingFeature("InferIsolatedConformances")
  ]
)

If you want to apply the settings to all targets, including test targets, add the following to the bottom of your Package.swift file:

for target in package.targets {
  var settings = target.swiftSettings ?? []
  settings.append(contentsOf: [
    .defaultIsolation(MainActor.self),
    .enableUpcomingFeature("NonisolatedNonsendingByDefault"),
    .enableUpcomingFeature("InferIsolatedConformances")
  ])
  target.swiftSettings = settings
}

Initial Experiences

I’m writing this post using Xcode 26 beta 3 and I would say this is still a work-in-progress. One common issue is with protocols like CodingKey which expect to be nonisolated:

struct AppSettings: Codable  {
  let name: String

  private enum CodingKeys: String, CodingKey {
    case name
  }
  ...
}

That generates a compiler warning:

Conformance of ‘AppSettings.CodingKeys’ to protocol ‘CodingKey’ crosses into main actor-isolated code and can cause data races

You can workaround it by marking the enum as nonisolated but a permanent fix is on the way.

I’ve also seen issues when the generated Bundle.module becomes isolated to @MainActor by default.

Learn More