About axiom-swift-modern
A Swift development skill that replaces legacy or commonly generated patterns with modern APIs, syntax, and concurrency practices. It is intended for developers writing or reviewing Swift code, and emphasizes edge cases and safer defaults, including Swift 6.3-oriented concurrency guidance.
Key features
- 01Modern Foundation API replacements
- 02Concise modern Swift syntax
- 03SwiftUI convenience API guidance
- 04Swift 6.3 concurrency defaults
- 05Guidance on avoiding unsafe escape hatches
Use cases
- 01Update code using legacy APIs
- 02Review generated Swift for outdated patterns
- 03Choose concurrency and actor-isolation patterns
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ charleswiltgen/ axiom --skill axiom-swift-modernAfter installing, type/axiom-swift-modernin Claude Code to confirm it loaded.
Details
From the project READMEModern Swift Idioms
Purpose
Claude frequently generates outdated Swift patterns from its training data. This skill corrects the most common ones — patterns that compile fine but use legacy APIs when modern equivalents are clearer, more efficient, or more correct.
Philosophy: "Don't repeat what LLMs already know — focus on edge cases, surprises, soft deprecations." (Paul Hudson)
Modern API Replacements
| Old Pattern | Modern Swift | Since | Why |
|---|---|---|---|
Date() | Date.now | 5.6 | Clearer intent |
filter { }.count | count(where:) | 5.0 | Single pass, no intermediate allocation |
replacingOccurrences(of:with:) | replacing(_:with:) | 5.7 | Swift native, no Foundation bridge |
CGFloat | Double | 5.5 | Implicit bridging; exceptions: optionals, inout, ObjC-bridged APIs |
Task.sleep(nanoseconds:) | Task.sleep(for: .seconds(1)) | 5.7 | Type-safe Duration API |
DateFormatter() | .formatted() / FormatStyle | 5.5 | No instance management, localizable by default |
String(format: "%.2f", val) | val.formatted(.number.precision(.fractionLength(2))) | 5.5 | Type-safe, localized |
localizedCaseInsensitiveContains() | localizedStandardContains() | 5.0 | Handles diacritics, ligatures, width variants |
"\(firstName) \(lastName)" | PersonNameComponents with .formatted() | 5.5 | Respects locale name ordering |
"yyyy-MM-dd" with DateFormatter | try Date(string, strategy: .iso8601) | 5.6 | Modern parsing (throws); use "y" not "yyyy" for display |
contains() on user input | localizedStandardContains() | 5.0 | Required for correct text search/filtering |
Modern Syntax
| Old Pattern | Modern Swift | Since |
|---|---|---|
if let value = value { | if let value { | 5.7 |
Explicit return in single-expression | Omit return; if/switch are expressions | 5.9 |
Circle() in modifiers | .circle (static member lookup) | 5.5 |
import UIKit alongside import SwiftUI | Often not needed — SwiftUI re-exports most UIKit/AppKit types. Retain for UIKit-only APIs (UIApplication, etc.) | 5.5 |
Foundation Modernization
| Old Pattern | Modern Foundation | Since |
|---|---|---|
FileManager.default.urls(for: .documentDirectory, ...) | URL.documentsDirectory | 5.7 |
url.appendingPathComponent("file") | url.appending(path: "file") | 5.7 |
books.sorted { $0.author < $1.author } (repeated) | Conform to Comparable, call .sorted() | — |
"yyyy" in date format for display | "y" — correct in all calendar systems | — |
SwiftUI Convenience APIs Claude Misses
ContentUnavailableView.search(text: searchText)(iOS 17+) automatically includes the search term — no need to compose a custom stringLabeledContentin Forms (iOS 16+) provides consistent label alignment without manual HStack layoutconfirmationDialog()must attach to triggering UI — Liquid Glass morphing animations depend on the source element
Swift 6.3 Concurrency Posture
Write Swift 6.3-first code, not Swift 5-era code. These defaults apply to ALL new Swift code, not just when concurrency errors appear.
| Default | Rationale |
|---|---|
| Assume strict concurrency and MainActor default isolation for app/UI modules | Swift 6.3 language mode; Xcode 26+ default for new projects |
| Prefer async/await over GCD, DispatchGroup, and callback pyramids | GCD is a bridge pattern for legacy APIs, not default architecture |
Async does not mean background — use @concurrent (Swift 6.2+) to force off-main | Async functions resume on the same actor they were called from |
Prefer structured concurrency (async let, TaskGroup) over unstructured Task {} | Structured tasks propagate cancellation and errors automatically |
Do not use Task.detached unless there is a specific, stated reason | Loses actor context, priority, and task-local values |
| Prefer Sendable structs/enums for data that crosses actor boundaries | Value types are inherently safe to share |
| Use actors only for truly shared mutable state across concurrency domains | Don't make every class an actor — UI code stays @MainActor |
Treat @unchecked Sendable, @preconcurrency, nonisolated(unsafe) as temporary bridge tools | Each should have a removal ticket, not be permanent |
| Do not add escape hatches just to silence compiler errors | They hide data races that crash in production |
For detailed patterns, decision trees, and error-specific guidance, see axiom-swift-concurrency.
Common Claude Hallucinations
These patterns appear frequently in Claude-generated code:
- Creates
DateFormatterinstances inline — Use.formatted()orFormatStyleinstead. If a formatter must exist, make itstatic let. - Uses
DispatchQueue.main.async— Use@MainActororMainActor.run. GCD is a bridge pattern, not a default. - Uses
DispatchQueue.global().asyncfor background work — Use@concurrent(Swift 6.2+) or extract to an actor. - Uses
Task.detachedto "make it background" — Use@concurrent.Task.detachedloses actor context. - Uses
CGFloatfor SwiftUI parameters —Doubleworks everywhere since Swift 5.5 implicit bridging. - Generates
guard let x = x else— Useguard let x elseshorthand. - Returns explicitly in single-expression computed properties — Omit
return. - Spawns unstructured
Task {}in loops — UseTaskGroupfor dynamic parallel work. - Adds
@unchecked Sendableto silence warnings — Convert to actor or proper Sendable type.
Resources
Skills: axiom-swift-performance, axiom-swift-concurrency, axiom-swiftui-architecture