Swift Macros vs Sourcery Comparison

Swift 5.9+ compile-time native macros

VS
Sourcery

External Swift code generation tool (Stencil-based)

8 min readiOS

Quick Verdict

For new Swift 5.9+ projects, Macros are the clear choice — native and future-proof. For legacy codebases (5.0-5.8), Sourcery remains the pragmatic option. As a migration path, phase out Sourcery and move to Macros; by 2027, Sourcery usage will be niche.

Swift MacrosSourcery
Read the full verdict

Score Comparison

Loading chart...

Detailed Scoring

Detailed Scoring: Swift Macros and Sourcery — category-by-category scores out of 10
CategorySwift MacrosSourcery
Performance
9/10
7/10
Ease of Learning
7/10
8/10
Ecosystem
8/10
8/10
Community
8/10
9/10
Job Market
8/10
6/10
Future-Proof
10/10
6/10

Pros & Cons

Swift Macros

Pros

  • Native to the Swift compiler — seamless integration
  • Type-safe, with syntax errors caught at compile time
  • Full IDE support (Xcode autocomplete, navigation)
  • Built-in macros like @Observable, @Query, and #Preview
  • Widely adopted across SwiftUI, SwiftData, and the Testing framework
  • Async-safe and thread-safe by design
  • Platform-agnostic (iOS, macOS, Linux)
  • Future-proof — officially promoted by Apple

Cons

  • Swift 5.9+ only (Xcode 15+)
  • Learning curve requires knowledge of the SwiftSyntax API
  • Debugging is harder — need #expand to inspect macro expansion
  • Adds to build time (on first build)

Best For

New Swift 5.9+ projectsSwiftUI and SwiftData projectsLibrary and framework authorsBuilding type-safe DSLsFollowing Apple's official pattern (Testing framework)

Sourcery

Pros

  • Swift 5.0+ compatible (works with older projects)
  • External build phase — runs at build time, not at runtime
  • Stencil templating — intuitive to write
  • Built-in annotations like AutoMockable, AutoLenses, AutoEquatable
  • Integrates into Xcode via a build phase script
  • Extensive community template library
  • Generated code is checked into git (inspectable)
  • Extensive support for mocking

Cons

  • External dependency (unlike native Swift Macros)
  • Adds a build phase — no clean native integration
  • Generated files live in the repo — review noise
  • Swift type-system limitations (weaker than macros)

Best For

Legacy Swift projects (5.0-5.8)Extensive mocking (test suites)Cross-team boilerplate reductionSpecific generation patterns (Lens, Equatable)A bridge before migration

Code Comparison

Swift Macros
@freestanding(expression)
public macro Color(_ hex: String) -> Color = #externalMacro(
    module: "MyMacros",
    type: "ColorFromHexMacro"
)

// Usage:
let primary = #Color("#4A90E2")
// Compile-time expansion → UIColor(red: 0.29, green: 0.56, ...)
Sourcery
// Sourcery annotation
// sourcery: AutoMockable
protocol UserService {
    func fetchUser(id: String) async throws -> User
    func updateUser(_ user: User) async throws
}

// Generated (auto) — MockUserService.generated.swift:
// class MockUserService: UserService { ... }

Conclusion

For new Swift 5.9+ projects, Macros are the clear choice — native and future-proof. For legacy codebases (5.0-5.8), Sourcery remains the pragmatic option. As a migration path, phase out Sourcery and move to Macros; by 2027, Sourcery usage will be niche.

Get Free Consultation
FAQ

Frequently Asked Questions

Yes — Macros as primary with Sourcery for mocking works as a hybrid setup, though a single tool is the ideal end state.

Related Blog Posts

View All Posts

Related Projects

View All Projects
All Comparisons