Introducing MacroBrewery: A Collection of Swift Macros for Code Generation
If you’ve worked on a Swift codebase of any size, you’ve written the same boilerplate code hundreds of times. Memberwise initializers. Builder patterns. Enum case accessors. Test stubs. It’s tedious, error-prone, and frankly, boring.
Swift 5.9 introduced macros, and I finally had a way to solve this properly. So I built MacroBrewery, a collection of macros that generate the repetitive code I was tired of writing by hand.
What’s Included
@AutoInit
Generates memberwise initializers that improve on Swift’s built-in one: optionals default to nil, properties with default values preserve them as parameter defaults, and you can set any access level.
@AutoInit(accessLevel: "public")
public struct User {
var name: String
var email: String?
var isActive: Bool = true
}
// Generates: public init(name: String, email: String? = nil, isActive: Bool = true)
@AutoBuilder
Creates a Builder pattern with a fluent API. Useful for types with lots of optional configuration.
@AutoBuilder
struct NetworkRequest {
var url: URL
var method: String = "GET"
var timeout: TimeInterval = 30
}
let request = NetworkRequest.builder()
.url(myURL)
.method("POST")
.build()
@EnumProperties
Generates computed properties for enum cases. No more switch statements just to check state or extract associated values.
@EnumProperties
enum LoadingState {
case idle
case loading(progress: Double)
case success(data: Data)
case failure(error: Error)
}
let state = LoadingState.loading(progress: 0.5)
state.isLoading // true
state.loading // Optional(0.5)
@AutoStub
Creates factory methods for testing. Pair it with @Stub to specify default values.
@AutoStub
struct User {
@Stub("Test User")
var name: String
@Stub(25)
var age: Int
}
let testUser = User.stub()
@AutoTypeErase
Generates type-erased wrappers like AnyPublisher, but for your own protocols.
@AutoTypeErase
protocol Animal {
var name: String { get }
func speak() async throws
}
// Generates: struct AnyAnimal: Animal { ... }
@AutoParse
Creates initializers for mapping from DTOs to domain models.
@AutoParse(from: UserDTO.self)
struct User {
var name: String
var age: Int
}
// Generates: init(_ raw: UserDTO) { ... }
Getting Started
Add it to your Package.swift:
dependencies: [
.package(url: "https://github.com/evandcoleman/MacroBrewery.git", from: "0.1.0")
]
Requires Swift 5.9+ and supports iOS 13+, macOS 10.15+, tvOS 13+, and watchOS 6+.
Open Source
I’ve released MacroBrewery under the MIT license. The code is on GitHub if you want to see how the macros are implemented or contribute new ones.
If you end up using it, I’d love to hear about it.