Skip to content
| Marketplace
Sign in
Visual Studio Code>Linters>Swift 6 Concurrency Migration LintNew to Visual Studio Code? Get it now.
Swift 6 Concurrency Migration Lint

Swift 6 Concurrency Migration Lint

ReadyStack

| (0) | Free
Finds the Swift 6 strict-concurrency blockers in your .swift files — global var, static var shared, @unchecked Sendable, DispatchQueue.main.async inside async — before you flip the language mode.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Swift 6 Concurrency Migration Lint

Swift 6 Concurrency Migration Lint

Swift 6 language mode turns data-race safety from a warning into a compiler error. Code that builds cleanly in Swift 5 — a static var shared singleton, a top-level var cache, a DispatchQueue used as a lock — stops building the moment a target is switched over. Assistants still write that Swift 5 shape by default, because most of the Swift on the public internet predates the strict-concurrency rules.

This extension reads **/*.swift and reports the lines that will not survive the switch, before you flip the flag.

What it checks

Eleven rules, all of them about isolation and mutable state:

Rule Severity What it catches
global_var error top-level var — rejected as non-concurrency-safe global
static_var error static var shared and friends — the same global, inside a type
dispatch_semaphore error DispatchSemaphore blocking a cooperative-pool thread
tools_version_5 error swift-tools-version: 5.x in Package.swift — the package can never enter Swift 6 mode
unchecked_sendable warn @unchecked Sendable — checker silenced, race unchanged
nonisolated_unsafe warn nonisolated(unsafe) escape hatch
queue_sync_lock warn serial-queue .sync { } locking, invisible to the isolation checker
escaping_not_sendable warn @escaping without @Sendable
detached_task warn Task.detached leaving actor isolation
dispatch_main_in_async warn DispatchQueue.main.async in a file that already uses async/await
preconcurrency_import info @preconcurrency import shim hiding module errors

Each finding carries the line number, the reason the Swift 6 compiler objects, and the replacement shape (actor, @MainActor, static let, await, Mutex).

Measured on the bundled fixtures

_fixtures/dirty.swift is 47 lines of ordinary Swift 5 service code. The engine returns 13 findings, 6 of them build-blocking errors. _fixtures/clean.swift is the same service rewritten as an actor with a Sendable value type and returns 0 findings. The two files are in the repository, so the numbers above can be reproduced.

Free and paid

The free extension lints the files you open and names every blocker with its line and its fix — that job finishes without a licence key. The paid tier exports one migration report for the whole repository: every file ranked by blocking errors, in a form you can commit, attach to a ticket, or read in CI. The split is ownership and scale, not a crippled free tier: nothing is hidden, watermarked, or counted down.

Yardstick

One hour of a contract iOS engineer, at the $100/hour rates common in the US market, costs more than this licence does once.

The same engine in a browser

index.html is a single page that runs ext/engine.js with the same ext/rules.json — paste a Swift file, get the same findings, no install and no upload. Hub page: https://getreadystack.com/tools/swift6-concurrency-lint

Notes

  • The lint is textual, not a full Swift parser: it reads lines, skips comments, and does not resolve types. It is a migration triage list, not a substitute for a Swift 6 build.
  • Rules live in ext/rules.json. The list is a flat array; adding a rule is adding an object.
  • No telemetry, no network calls during linting.
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft