Overview
Swift 6.4 is the current release (September 2026, bundled with Xcode 27); Swift 6.3 shipped in March 2026. Swift 6 language mode turns data-race findings into compile errors, and Swift 6.2 added approachable concurrency so most app code needs few isolation annotations. Read general-principles first; the rules below route to the page that carries the detail.
Use Swift 6 language mode for new code and migrate per target
Language mode 6 reports data races as errors. For an existing project, enable it one target at a time (see swift-modules), starting with leaf modules, and keep the rest on Swift 5 mode until their warnings are clear. Defaults for isolation and @concurrent are in swift-concurrency.
Default to value types, small protocols, and private access
Use struct and enum unless identity matters, define behavior with narrow protocols, and start every declaration at the narrowest access level that compiles. A non-public struct whose stored properties are all Sendable is Sendable without a declaration. Details: swift-protocols and swift-modules.
Never force-unwrap; throw when the reason matters
! and try! are crashes. Use guard let and ??, and a thrown error when the caller needs to know why. Catch at the boundary and translate. Details, including when typed throws is worth it: swift-error-handling.
Use @Observable for model state
Prefer the Observation framework’s @Observable over ObservableObject and @Published on iOS 17 and later; it tracks reads per property, so a view re-renders only for properties it read. Own the model with @State in the creating view. UI patterns are in swiftui.
@Observable
final class FeedModel {
var items: [FeedItem] = []
func load() async { /* ... */ }
}Write new tests with Swift Testing
Swift Testing (@Test, #expect) is the framework for new unit tests; XCTest remains for UI and performance tests. See swift-testing.