mcpField
C
concurrency-expert

concurrency-expert

github.com/patrickserranoDevelopment1361 installsUpdated 41w ago
Repository

About concurrency-expert

concurrency-expert is a skill for reviewing and fixing concurrency issues in Swift 6.2+ codebases. It uses actor isolation, Sendable safety, and current concurrency patterns while aiming to preserve behavior.

Key features

  1. 01Triage compiler diagnostics and actor context
  2. 02Apply actor isolation to UI-bound code
  3. 03Protect shared and global state
  4. 04Move work off the main actor
  5. 05Guide Swift concurrency migration

Use cases

  1. 01Resolve strict concurrency compiler errors
  2. 02Safely isolate UI-bound types
  3. 03Move background processing off the main actor

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/patrickserrano/skills --skill concurrency-expert

After installing, type/concurrency-expertin Claude Code to confirm it loaded.

Details

From the project README

Swift Concurrency Expert

Overview

Review and fix Swift Concurrency issues in Swift 6.2+ codebases by applying actor isolation, Sendable safety, and modern concurrency patterns with minimal behavior changes.

Workflow

1. Triage the issue
  • Capture the exact compiler diagnostics and the offending symbol(s)
  • Check project concurrency settings: Swift language version (6.2+), strict concurrency level
  • Check if approachable concurrency (default actor isolation / main-actor-by-default) is enabled
  • Identify the current actor context (@MainActor, actor, nonisolated)
  • Confirm whether the code is UI-bound or intended to run off the main actor
2. Apply the smallest safe fix

Prefer edits that preserve existing behavior while satisfying data-race safety.

Common fixes:

IssueFix
UI-bound typesAnnotate the type or members with @MainActor
Protocol conformance on main actor typesMake conformance isolated: extension Foo: @MainActor SomeProtocol
Global/static stateProtect with @MainActor or move into an actor
Background workUse @concurrent async function on a nonisolated type
Sendable errorsPrefer immutable/value types; add Sendable only when correct

Swift 6.2 Key Changes

Default Actor Isolation

Swift 6.2 stays single-threaded by default until you choose to introduce concurrency:

// In Swift 6.2 with approachable concurrency enabled,
// this no longer produces a data race error
@MainActor
final class StickerModel {
    let photoProcessor = PhotoProcessor()

    func extractSticker(_ item: PhotosPickerItem) async throws -> Sticker? {
        guard let data = try await item.loadTransferable(type: Data.self) else {
            return nil
        }
        // Safe - runs on main actor by default
        return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
    }
}
Isolated Conformances

Conformances that need main actor state are now supported:

protocol Exportable {
    func export()
}

// Isolated conformance - safe because compiler ensures
// it's only used on the main actor
extension StickerModel: @MainActor Exportable {
    func export() {
        photoProcessor.exportAsPNG()
    }
}
Protecting Global State
// Protect with @MainActor
@MainActor
final class StickerLibrary {
    static let shared: StickerLibrary = .init()
}

// Or enable main-actor-by-default mode for the whole project
Offloading Work to Background

Use @concurrent to explicitly run code on the concurrent thread pool:

nonisolated struct PhotoProcessor {
    @concurrent
    func process(data: Data) async -> ProcessedPhoto? {
        // Runs on background thread
    }
}

// Caller adds await
processedPhotos[item.id] = await PhotoProcessor().process(data: data)

Migration Checklist

  1. Check Swift version in build settings (needs 6.2+)
  2. Enable approachable concurrency features in build settings
  3. Run Swift migration tooling: swift.org/migration
  4. Fix remaining compiler errors using patterns above
  5. Test thoroughly - concurrency bugs may surface at runtime

Common Patterns

UI-Bound Class
@MainActor
final class ViewModel {
    var items: [Item] = []

    func load() async {
        items = try await service.fetchItems()
    }
}
Background Processing
nonisolated struct ImageProcessor {
    @concurrent
    static func resize(_ image: UIImage, to size: CGSize) async -> UIImage {
        // Heavy work runs off main actor
    }
}
Actor for Shared Mutable State
actor Cache {
    private var storage: [String: Data] = [:]

    func get(_ key: String) -> Data? {
        storage[key]
    }

    func set(_ key: String, value: Data) {
        storage[key] = value
    }
}

Build Settings

Enable in Xcode under Swift Compiler - Concurrency:

  • SWIFT_STRICT_CONCURRENCY = complete
  • Approachable concurrency features (Swift 6.2+)

Or in Package.swift:

swiftSettings: [
    .enableExperimentalFeature("StrictConcurrency")
]

Comments

Markdown supported