mcpField
A
axiom-swift-modern

axiom-swift-modern

github.com/charleswiltgenDevelopment1.2k69 installsUpdated today
Repository

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

  1. 01Modern Foundation API replacements
  2. 02Concise modern Swift syntax
  3. 03SwiftUI convenience API guidance
  4. 04Swift 6.3 concurrency defaults
  5. 05Guidance on avoiding unsafe escape hatches

Use cases

  1. 01Update code using legacy APIs
  2. 02Review generated Swift for outdated patterns
  3. 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-modern

After installing, type/axiom-swift-modernin Claude Code to confirm it loaded.

Details

From the project README

Modern 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 PatternModern SwiftSinceWhy
Date()Date.now5.6Clearer intent
filter { }.countcount(where:)5.0Single pass, no intermediate allocation
replacingOccurrences(of:with:)replacing(_:with:)5.7Swift native, no Foundation bridge
CGFloatDouble5.5Implicit bridging; exceptions: optionals, inout, ObjC-bridged APIs
Task.sleep(nanoseconds:)Task.sleep(for: .seconds(1))5.7Type-safe Duration API
DateFormatter().formatted() / FormatStyle5.5No instance management, localizable by default
String(format: "%.2f", val)val.formatted(.number.precision(.fractionLength(2)))5.5Type-safe, localized
localizedCaseInsensitiveContains()localizedStandardContains()5.0Handles diacritics, ligatures, width variants
"\(firstName) \(lastName)"PersonNameComponents with .formatted()5.5Respects locale name ordering
"yyyy-MM-dd" with DateFormattertry Date(string, strategy: .iso8601)5.6Modern parsing (throws); use "y" not "yyyy" for display
contains() on user inputlocalizedStandardContains()5.0Required for correct text search/filtering

Modern Syntax

Old PatternModern SwiftSince
if let value = value {if let value {5.7
Explicit return in single-expressionOmit return; if/switch are expressions5.9
Circle() in modifiers.circle (static member lookup)5.5
import UIKit alongside import SwiftUIOften not needed — SwiftUI re-exports most UIKit/AppKit types. Retain for UIKit-only APIs (UIApplication, etc.)5.5

Foundation Modernization

Old PatternModern FoundationSince
FileManager.default.urls(for: .documentDirectory, ...)URL.documentsDirectory5.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 string
  • LabeledContent in Forms (iOS 16+) provides consistent label alignment without manual HStack layout
  • confirmationDialog() 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.

DefaultRationale
Assume strict concurrency and MainActor default isolation for app/UI modulesSwift 6.3 language mode; Xcode 26+ default for new projects
Prefer async/await over GCD, DispatchGroup, and callback pyramidsGCD is a bridge pattern for legacy APIs, not default architecture
Async does not mean background — use @concurrent (Swift 6.2+) to force off-mainAsync 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 reasonLoses actor context, priority, and task-local values
Prefer Sendable structs/enums for data that crosses actor boundariesValue types are inherently safe to share
Use actors only for truly shared mutable state across concurrency domainsDon't make every class an actor — UI code stays @MainActor
Treat @unchecked Sendable, @preconcurrency, nonisolated(unsafe) as temporary bridge toolsEach should have a removal ticket, not be permanent
Do not add escape hatches just to silence compiler errorsThey 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:

  1. Creates DateFormatter instances inline — Use .formatted() or FormatStyle instead. If a formatter must exist, make it static let.
  2. Uses DispatchQueue.main.async — Use @MainActor or MainActor.run. GCD is a bridge pattern, not a default.
  3. Uses DispatchQueue.global().async for background work — Use @concurrent (Swift 6.2+) or extract to an actor.
  4. Uses Task.detached to "make it background" — Use @concurrent. Task.detached loses actor context.
  5. Uses CGFloat for SwiftUI parameters — Double works everywhere since Swift 5.5 implicit bridging.
  6. Generates guard let x = x else — Use guard let x else shorthand.
  7. Returns explicitly in single-expression computed properties — Omit return.
  8. Spawns unstructured Task {} in loops — Use TaskGroup for dynamic parallel work.
  9. Adds @unchecked Sendable to silence warnings — Convert to actor or proper Sendable type.

Resources

Skills: axiom-swift-performance, axiom-swift-concurrency, axiom-swiftui-architecture

Comments

Markdown supported