Top Related Projects
A set of Swift libraries for parsing, inspecting, generating, and transforming Swift source code.
An adorable little framework and command line tool for interacting with SourceKit.
A tool to enforce Swift style and conventions.
A simple, decentralized dependency manager for Cocoa
Strong typed, autocompleted resources like images, fonts and segues in Swift projects
The Swift code generator for your assets, storyboards, Localizable.strings, … — Get rid of all String-based APIs!
Quick Overview
Sourcery is a code generation tool for Swift that automates the creation of boilerplate code. It uses templates to scan your Swift source files and generate new code, saving developers time and reducing errors in repetitive tasks.
Pros
- Increases productivity by automating repetitive coding tasks
- Reduces human error in boilerplate code generation
- Highly customizable with a powerful templating system
- Integrates well with various build systems and IDEs
Cons
- Requires initial setup and learning curve to create custom templates
- May add complexity to the build process for some projects
- Generated code can be difficult to debug if templates are not well-designed
- Potential for overuse, leading to unnecessarily complex codebases
Code Examples
- Generating a string representation for an enum:
// sourcery:inline:auto:MyEnum.StringRepresentation
extension MyEnum {
var stringValue: String {
switch self {
{% for case in enum.cases %}
case .{{ case.name }}: return "{{ case.name }}"
{% endfor %}
}
}
}
// sourcery:end
- Creating a protocol conformance for Equatable:
// sourcery:inline:auto:AutoEquatable
extension {{ type.name }}: Equatable {
static func == (lhs: {{ type.name }}, rhs: {{ type.name }}) -> Bool {
{% for variable in type.storedVariables %}
guard lhs.{{ variable.name }} == rhs.{{ variable.name }} else { return false }
{% endfor %}
return true
}
}
// sourcery:end
- Generating a mock for unit testing:
// sourcery:inline:auto:MockGenerator
class Mock{{ protocol.name }}: {{ protocol.name }} {
{% for method in protocol.methods %}
var {{ method.callName }}Called = false
var {{ method.callName }}Closure: ({% for parameter in method.parameters %}{{ parameter.typeName }}{% if not forloop.last %}, {% endif %}{% endfor %}) -> {{ method.returnTypeName }}?
func {{ method.name }} {
{{ method.callName }}Called = true
{% if not method.returnTypeName.isVoid %}
return {{ method.callName }}Closure?({% for parameter in method.parameters %}{{ parameter.name }}{% if not forloop.last %}, {% endif %}{% endfor %}) ?? <#Default Value#>
{% else %}
{{ method.callName }}Closure?({% for parameter in method.parameters %}{{ parameter.name }}{% if not forloop.last %}, {% endif %}{% endfor %})
{% endif %}
}
{% endfor %}
}
// sourcery:end
Getting Started
- Install Sourcery using CocoaPods, Homebrew, or download the binary.
- Create a configuration file named
.sourcery.yml
in your project root:
sources:
- ./YourProject
templates:
- ./Templates
output:
./Generated
- Create a template file (e.g.,
AutoEquatable.stencil
) in the Templates directory. - Run Sourcery:
sourcery --config .sourcery.yml
- Add the generated files to your Xcode project.
Competitor Comparisons
A set of Swift libraries for parsing, inspecting, generating, and transforming Swift source code.
Pros of swift-syntax
- Official Apple project, ensuring long-term support and compatibility
- Provides a more comprehensive and low-level access to Swift's Abstract Syntax Tree (AST)
- Designed for use in various Swift tooling, including IDEs and linters
Cons of swift-syntax
- Steeper learning curve due to its lower-level nature
- Requires more manual work to implement code generation tasks
- Less focused on code generation specifically, as it's a general-purpose syntax parsing tool
Code Comparison
Sourcery (template-based code generation):
{% for type in types.implementing.AutoCodable %}
extension {{ type.name }}: Codable {
// Generated Codable implementation
}
{% endfor %}
swift-syntax (manual AST manipulation):
let structDecl = StructDeclSyntax(
attributes: [],
modifiers: [],
structKeyword: .structKeyword(),
identifier: .identifier("MyStruct"),
genericParameterClause: nil,
inheritanceClause: nil,
genericWhereClause: nil,
members: MemberDeclBlockSyntax(
leftBrace: .leftBraceToken(),
members: MemberDeclListSyntax([]),
rightBrace: .rightBraceToken()
)
)
An adorable little framework and command line tool for interacting with SourceKit.
Pros of SourceKitten
- Focused on Swift and Objective-C parsing and analysis
- Provides a command-line tool for easy integration into scripts and workflows
- Offers a lightweight API for accessing source code structure and documentation
Cons of SourceKitten
- Limited to parsing and analysis, doesn't generate code
- Requires more manual work to implement code generation or modification
- Less suitable for complex code generation tasks
Code Comparison
SourceKitten example (parsing Swift code):
let file = File(contents: "struct Example {}")
let structure = Structure(file: file)
print(structure.dictionary)
Sourcery example (generating code):
{% for type in types.all where type.based.AutoCodable %}
extension {{ type.name }}: Codable {
// Generated Codable implementation
}
{% endfor %}
While SourceKitten excels at parsing and analyzing Swift and Objective-C code, Sourcery is designed for code generation based on templates. SourceKitten provides a lower-level API for working with source code structure, while Sourcery offers a higher-level abstraction for generating code based on existing types and templates.
A tool to enforce Swift style and conventions.
Pros of SwiftLint
- Focuses specifically on enforcing Swift style and conventions
- Provides a large set of pre-defined rules out of the box
- Integrates well with Xcode and CI/CD pipelines
Cons of SwiftLint
- Limited to linting and doesn't generate code
- Can be more rigid and less customizable for complex scenarios
- May require more setup and configuration for project-specific rules
Code Comparison
SwiftLint example:
// SwiftLint configuration
disabled_rules:
- trailing_whitespace
opt_in_rules:
- empty_count
- missing_docs
Sourcery example:
// Sourcery template
{% for type in types.implementing.AutoCodable %}
extension {{ type.name }}: Codable {
// Generated Codable implementation
}
{% endfor %}
SwiftLint is primarily used for enforcing coding style and conventions, while Sourcery is a code generation tool that can automate repetitive coding tasks. SwiftLint excels at maintaining consistent code quality across a project, whereas Sourcery shines in reducing boilerplate code and generating complex implementations based on templates.
A simple, decentralized dependency manager for Cocoa
Pros of Carthage
- Decentralized dependency manager, allowing direct use of GitHub repositories
- Builds frameworks binary, resulting in faster compilation times
- Supports multiple platforms (iOS, macOS, tvOS, watchOS)
Cons of Carthage
- Requires manual framework integration into Xcode project
- Slower initial setup compared to CocoaPods
- Limited to Swift and Objective-C projects
Code Comparison
Carthage:
github "Alamofire/Alamofire" ~> 5.0
github "ReactiveX/RxSwift" ~> 6.0
Sourcery:
// sourcery:inline:auto:MyClass.AutoCodable
enum CodingKeys: String, CodingKey {
case id, name, age
}
// sourcery:end
While Carthage is a dependency manager focused on integrating external libraries, Sourcery is a code generation tool for Swift. Carthage simplifies the process of adding and managing third-party dependencies in iOS and macOS projects. On the other hand, Sourcery automates the creation of boilerplate code, enhancing productivity and reducing errors in Swift development.
Carthage excels in providing a decentralized approach to dependency management, offering more control over the integration process. However, it requires more manual setup compared to other dependency managers. Sourcery shines in its ability to generate custom code based on templates, saving developers time and reducing repetitive tasks. Both tools serve different purposes in the iOS development ecosystem and can be used complementarily in projects.
Strong typed, autocompleted resources like images, fonts and segues in Swift projects
Pros of R.swift
- Focused specifically on resource management in iOS/macOS projects
- Generates strongly typed accessors for images, fonts, and localized strings
- Simpler setup and usage for resource-related code generation
Cons of R.swift
- Limited to resource management, less versatile than Sourcery
- May require more manual updates when adding new resources
- Less customizable for complex code generation scenarios
Code Comparison
R.swift generated code:
R.image.backgroundImage
R.string.localizable.welcomeMessage
R.font.helveticaNeue(size: 16)
Sourcery equivalent (custom template required):
enum R {
enum Image {
static let backgroundImage = UIImage(named: "backgroundImage")
}
enum String {
static let welcomeMessage = NSLocalizedString("welcomeMessage", comment: "")
}
}
R.swift provides more concise and type-safe access to resources out of the box, while Sourcery requires custom templates but offers greater flexibility for various code generation tasks beyond resource management.
The Swift code generator for your assets, storyboards, Localizable.strings, … — Get rid of all String-based APIs!
Pros of SwiftGen
- Focused specifically on Swift code generation for assets, strings, and other resources
- Provides built-in templates for common use cases, making it easier to get started
- Integrates well with Xcode and CocoaPods for seamless workflow
Cons of SwiftGen
- Limited to generating code for specific resource types
- Less flexible for custom code generation scenarios
- Requires separate configuration files for different resource types
Code Comparison
SwiftGen example:
enum L10n {
static let welcome = L10n.tr("Localizable", "welcome")
static let goodbye = L10n.tr("Localizable", "goodbye")
}
Sourcery example:
{% for variable in type.variables %}
var {{ variable.name }}: {{ variable.typeName }} {
// Custom implementation
}
{% endfor %}
SwiftGen is tailored for generating Swift code from various resource types, making it ideal for iOS and macOS developers who want to automate the creation of type-safe accessors for assets, localized strings, and other resources. It offers a more streamlined experience for these specific use cases.
Sourcery, on the other hand, is a more general-purpose code generation tool that can be used for a wider range of tasks. It provides greater flexibility and customization options, allowing developers to create complex templates for generating any type of code.
While SwiftGen excels in its focused approach, Sourcery offers more power and adaptability for diverse code generation needs across different programming languages and frameworks.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
In-Depth Sourcery guide is covered as part of my SwiftyStack engineering course.
Sourcery Pro provides a powerful Stencil editor and extends Xcode with the ability to handle live AST templates: available on Mac App Store
https://user-images.githubusercontent.com/1468993/114271090-f6c19200-9a0f-11eb-9bd8-d7bb15129eb2.mp4
Sourcery is a code generator for Swift language, built on top of Apple's own SwiftSyntax. It extends the language abstractions to allow you to generate boilerplate code automatically.
It's used in over 40,000 projects on both iOS and macOS and it powers some of the most popular and critically-acclaimed apps you have used (including Airbnb, Bumble, New York Times). Its massive community adoption was one of the factors that pushed Apple to implement derived Equality and automatic Codable conformance. Sourcery is maintained by a growing community of contributors.
Try Sourcery for your next project or add it to an existing one -- you'll save a lot of time and be happy you did!
TL;DR
Sourcery allows you to get rid of repetitive code and create better architecture and developer workflows.
An example might be implementing Mocks
for all your protocols, without Sourcery you will need to write hundreds lines of code per each protocol like this:
class MyProtocolMock: MyProtocol {
//MARK: - sayHelloWith
var sayHelloWithNameCallsCount = 0
var sayHelloWithNameCalled: Bool {
return sayHelloWithNameCallsCount > 0
}
var sayHelloWithNameReceivedName: String?
var sayHelloWithNameReceivedInvocations: [String] = []
var sayHelloWithNameClosure: ((String) -> Void)?
func sayHelloWith(name: String) {
sayHelloWithNameCallsCount += 1
sayHelloWithNameReceivedName = name
sayHelloWithNameReceivedInvocations.append(name)
sayHelloWithNameClosure?(name)
}
}
and with Sourcery ?
extension MyProtocol: AutoMockable {}
Sourcery removes the need to write any of the mocks code, how many protocols do you have in your project? Imagine how much time you'll save, using Sourcery will also make every single mock consistent and if you refactor or add properties, the mock code will be automatically updated for you, eliminating possible human errors.
Sourcery can be applied to arbitrary problems across your codebase, if you can describe an algorithm to another human, you can automate it using Sourcery.
Most common uses are:
- Equality & Hashing
- Enum cases & Counts
- Lenses
- Mocks & Stubs
- LinuxMain
- Decorators
- Persistence and advanced Codable
- Property level diffing
But how about more specific use-cases, like automatically generating all the UI for your app BetaSetting
? you can use Sourcery for that too
Once you start writing your own template and learn the power of Sourcery you won't be able to live without it.
How To Get Started
There are plenty of tutorials for different uses of Sourcery, and you can always ask for help in our Swift Forum Category.
- The Magic of Sourcery is a great starting tutorial
- Generating Swift Code for iOS deals with JSON handling code
- How To Automate Swift Boilerplate with Sourcery generates conversions to dictionaries
- Codable Enums implements Codable support for Enumerations
- Sourcery Workshops
Quick Mocking Intro & Getting Started Video
You can also watch this quick getting started and intro to mocking video by Inside iOS Dev:
Installation
-
Binary form
Download the latest release with the prebuilt binary from release tab. Unzip the archive into the desired destination and run
bin/sourcery
-
brew install sourcery
-
Add
pod 'Sourcery'
to yourPodfile
and runpod update Sourcery
. This will download the latest release binary and will put it in your project's CocoaPods path so you will run it with$PODS_ROOT/Sourcery/bin/sourcery
If you only want to install the
sourcery
binary, you may want to use theCLI-Only
subspec:pod 'Sourcery', :subspecs => ['CLI-Only']
. -
mint run krzysztofzablocki/Sourcery
-
Building from Source
Download the latest release source code from the release tab or clone the repository and build Sourcery manually.
-
Building with Swift Package Manager
Run
swift build -c release
in the root folder and then copy.build/release/sourcery
to your desired destination.Note: JS templates are not supported when building with SPM yet.
-
Building with Xcode
Run
xcodebuild -scheme sourcery -destination generic/platform=macOS -archivePath sourcery.xcarchive archive
and export the binary from the archive.
-
-
SPM (for plugin use only) Add the package dependency to your
Package.swift
manifest from version1.8.3
.
.package(url: "https://github.com/krzysztofzablocki/Sourcery.git", from: "1.8.3")
- pre-commit
Add the dependency to
.pre-commit-config.yaml
.
- repo: https://github.com/krzysztofzablocki/Sourcery
rev: 1.9.1
hooks:
- id: sourcery
Documentation
Full documentation for the latest release is available here.
Linux Support
Linux support is described on this page.
Usage
Running the executable
Sourcery is a command line tool; you can either run it manually or in a custom build phase using the following command:
$ ./bin/sourcery --sources <sources path> --templates <templates path> --output <output path>
Note: this command differs depending on how you installed Sourcery (see Installation)
Swift Package command
Sourcery can now be used as a Swift package command plugin. In order to do this, the package must be added as a dependency to your Swift package or Xcode project (see Installation above).
To provide a configuration for the plugin to use, place a .sourcery.yml
file at the root of the target's directory (in the sources folder rather than the root of the package).
Running from the command line
To verify the plugin can be found by SwiftPM, use:
$ swift package plugin --list
To run the code generator, you need to allow changes to the project with the --allow-writing-to-package-directory
flag:
$ swift package --allow-writing-to-package-directory sourcery-command
Running in Xcode
Inside a project/package that uses this command plugin, right-click the project and select "SourceryCommand" from the "SourceryPlugins" menu group.
â ï¸ Note that this is only available from Xcode 14 onwards.
Command line options
--sources
- Path to a source swift files or directories. You can provide multiple paths using multiple--sources
option.--templates
- Path to templates. File or Directory. You can provide multiple paths using multiple--templates
options.--force-parse
- File extensions of Sourcery generated file you want to parse. You can provide multiple extension using multiple--force-parse
options. (i.e.file.toparse.swift
will be parsed even if generated by Sourcery if--force-parse toparse
). Useful when trying to implement a multiple phases generation.--force-parse
can also be used to process within a sourcery annotation. For example to process code withinsourcery:inline:auto:Type.AutoCodable
annotation you can use--force-parse AutoCodable
--output
[default: current path] - Path to output. File or Directory.--config
[default: current path] - Path to config file. File or Directory. See Configuration file.--args
- Additional arguments to pass to templates. Each argument can have an explicit value or will have implicittrue
value. Arguments should be separated with,
without spaces (i.e.--args arg1=value,arg2
). Arguments are accessible in templates viaargument.name
--watch
[default: false] - Watch both code and template folders for changes and regenerate automatically.--verbose
[default: false] - Turn on verbose logging--quiet
[default: false] - Turn off any logging, only emit errors--disableCache
[default: false] - Turn off caching of parsed data--prune
[default: false] - Prune empty generated files--version
- Display the current version of Sourcery--help
- Display help information--cacheBasePath
- Base path to the cache directory. Can be overriden by the config file.--buildPath
- Path to directory used when building from .swifttemplate files. This defaults to system temp directory--hideVersionHeader
[default: false] - Stop adding the Sourcery version to the generated files headers.--headerPrefix
- Additional prefix for headers.
Configuration file
Instead of CLI arguments, you can use a .sourcery.yml
configuration file:
sources:
- <sources path>
- <sources path>
templates:
- <templates path>
- <templates path>
forceParse:
- <string value>
- <string value>
output:
<output path>
args:
<name>: <value>
Read more about this configuration file here.
Issues
If you get an unverified developer warning when using binary zip distribution try:
xattr -dr com.apple.quarantine Sourcery-1.1.1
Contributing
Contributions to Sourcery are welcomed and encouraged!
It is easy to get involved. Please see the Contributing guide for more details.
A list of contributors is available through GitHub.
To clarify what is expected of our community, Sourcery has adopted the code of conduct defined by the Contributor Covenant. This document is used across many open source communities, and articulates my values well. For more, see the Code of Conduct.
Sponsoring
If you'd like to support Sourcery development you can do so through GitHub Sponsors or Open Collective, it's highly appreciated ðâ
If you are a company and would like to sponsor the project directly and get it's logo here, you can contact me directly
Sponsors
License
Sourcery is available under the MIT license. See LICENSE for more information.
Attributions
This tool is powered by
- Stencil and few other libs by Kyle Fuller
Thank you! to:
- Mariusz Ostrowski for creating the logo.
- Artsy Eidolon team, because we use their codebase as a stub data for performance testing the parser.
- Olivier Halligon for showing me his setup scripts for CLI tools which are powering our rakefile.
- JP Simard for creating SourceKitten that originally powered Sourcery and was instrumental in making this project happen.
Other Libraries / Tools
If you want to generate code for asset related data like .xib, .storyboards etc. use SwiftGen. SwiftGen and Sourcery are complementary tools.
Make sure to check my other libraries and tools, especially:
- KZPlayground - Powerful playgrounds for Swift and Objective-C
- KZFileWatchers - Daemon for observing local and remote file changes, used for building other developer tools (Sourcery uses it)
You can follow me on Twitter for news/updates about other projects I am creating.
Top Related Projects
A set of Swift libraries for parsing, inspecting, generating, and transforming Swift source code.
An adorable little framework and command line tool for interacting with SourceKit.
A tool to enforce Swift style and conventions.
A simple, decentralized dependency manager for Cocoa
Strong typed, autocompleted resources like images, fonts and segues in Swift projects
The Swift code generator for your assets, storyboards, Localizable.strings, … — Get rid of all String-based APIs!
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot