swift-syntax ships a placeholder where a version belongs, and its Bazel section pins tags from the old organisation
A set of Swift libraries for parsing, inspecting, generating, and transforming Swift source code.
At a glance
- What is it?
- The Swift library set behind Swift's macro system, working on a source-accurate tree of Swift source code. The README explains the mechanism in one paragraph and then leaves the version numbers to the reader: the SwiftPM snippet contains a placeholder, the versioning rule is illustrated with a version three majors behind the current one, and the two Bazel examples disagree with each other and with the repository's own name.
- Who is it for?
- swift-syntax is the right dependency if you are building a Swift macro, a source transformation tool, or anything that needs to read Swift accurately rather than approximately, and the source-accurate tree is the reason: macro expansion nodes are themselves syntax nodes, so a macro can hand back a tree instead of a string. Before you depend on it, settle three things.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Swift, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- swiftlang/swift-syntax3,719 ★ · +18
| Repository | 2026-09-24 | 2026-11-14 |
|---|---|---|
| swiftlang/swift-syntax | 3.7k | 3.7k |
18 Stars in the last 51 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
A source-accurate tree, with the macro system sitting on it
The whole design is one paragraph and it is the paragraph worth reading twice. The package is a set of libraries that work on a source-accurate tree representation of Swift source code, called the SwiftSyntax tree, and that tree forms the backbone of Swift's macro system: macro expansion nodes are themselves represented as SwiftSyntax nodes, and a macro generates a SwiftSyntax tree to be inserted into the source file. The word doing the work is accurate. A tool that regenerates source from a tree can lose comments, spacing and literal spelling; one that keeps the tree accurate to the bytes can rewrite a single expression and leave everything around it byte-identical. That is the property the rest of this repository exists to provide, and it is also why the library is generated rather than hand-written. Two places outside the repository let you see the tree directly: an interactive explorer for the tree of any source file, and an `Examples` directory in the repository itself with a set of example usages.
The manifest snippet ships a placeholder instead of a version
The Releases section tells you to add this to your `Package.swift`:
dependencies: [
.package(url: "https://github.com/swiftlang/swift-syntax.git", from: "<#latest swift-syntax tag#>"),
],The version field is a template placeholder, not a version. Copying the snippet produces a manifest that will not resolve until you replace it, and the file gives no other instruction about where to find the tag. The Xcode route is prose only: open the Package Dependencies tab, click the plus button, and search for the repository URL, with no mention of pinning a version either. For a library whose releases move fast, that is the first place a reader stumbles, and it is a one-line fix in the file.
Two snapshots claim the same prerelease version
The three most recent releases are 604.0.0, published on 2026-09-15 at 19:22, a prerelease tagged 605.0.0-prerelease-2026-09-15 published the same evening at 19:30, and an earlier prerelease tagged 605.0.0-prerelease-2026-06-26. So the stable line and the prerelease line were both touched on the same day, seven minutes apart, and the prerelease line has two published snapshots that carry the same version number with a date appended. A version constraint cannot express the difference between those two tags, and a script that pins `605.0.0-prerelease` has to decide which one it means. The prereleases are dated snapshots of a line that has not yet had a stable release, which is a reasonable thing to publish and an awkward thing to depend on.
The versioning rule is illustrated three majors behind
The rule is stated in a single sentence: releases are aligned with corresponding language and tooling releases, and the example given is that major version 509 of swift-syntax aligns with Swift 5.9. That example is three majors behind the current line, which is 604 with a 605 prerelease in flight. So the one concrete data point in the rule is not actionable, and the file does not say what 604 or 605 aligns with. If the alignment still holds, the mapping lives somewhere else. If it has changed, the sentence is stale while sounding current, which is the worse failure because a reader who trusts it will assume a relationship the file never claims for the present. One line updating 509 to the current major would fix it.
The Bazel section is experimental and its two examples disagree
The file is candid that the Bazel configuration is experimental and maintained by one named person, with Bzlmod support from release 509.0.0 onwards. The recommended form is a single dependency line, and the legacy form is an archive rule. They do not agree with each other. The recommended line pins `600.0.1`, which is behind the current 604.0.0. The legacy rule names the dependency `SwiftSyntax` where the recommended line names it `swift-syntax`, and it strips `swift-syntax-509.1.0` from an archive whose URL still points at the old `apple/swift-syntax` organisation rather than `swiftlang/swift-syntax`. Both snippets are also fenced as Python although they are Starlark. Nothing here is broken, and none of it is what you want in a build you intend to maintain.
A second target per library, optimized and undebuggable
Once you have the Bazel setup working, the libraries come with a choice attached. Each library has an associated `Library_opt` target, `SwiftSyntax_opt` being the example given, which forces SwiftSyntax to always build with optimizations enabled. The file states the trade honestly: it may help local runtime performance at the cost of debuggability and initial build time. So every library ships two targets, and the fast one is the one you cannot step through in a debugger. For a library whose main job is compile-time work on other people's code, that is a defensible default, but the cost lands on whoever is debugging a macro. The file also asks that issues about the Bazel configuration carry a specific label, which is a small sign the path is expected to generate bug reports.
Three build systems and a partly generated tree
The root of the repository carries `BUILD.bazel`, `MODULE.bazel` and `WORKSPACE` for Bazel, `CMakeLists.txt` with a `cmake/` directory for CMake, and `Package.swift` for SwiftPM, plus a `.bazelrc` and a `.bazelversion`. Three build descriptions for one library is unusual and it is a direct consequence of the package being a dependency of many toolchains. The tree is partly generated, which the entries admit: `CodeGeneration/` at the root next to `.license_header_template`, `.licenseignore` and a `.swift-format` configuration. Documentation is split awkwardly, with `Contributor Documentation/` and `Release Notes/` both carrying spaces in their names next to a separate `Changelog.md`. An `EditorExtension/` ships in the same repository as the library, and `Examples/` is its own package with its own manifest, README, sources and tests. The development utilities appear twice as well, once as `SwiftSyntaxDevUtils/` and once as `swift-syntax-dev-utils`. Two more root entries describe how the tree is kept honest: a license header template and a license ignore file, so the generated files carry the Apache-2.0 header the file points to as `LICENSE.txt`, and a formatter configuration in `.swift-format`.
Editorial conclusion
swift-syntax is the right dependency if you are building a Swift macro, a source transformation tool, or anything that needs to read Swift accurately rather than approximately, and the source-accurate tree is the reason: macro expansion nodes are themselves syntax nodes, so a macro can hand back a tree instead of a string. Before you depend on it, settle three things. The dependency snippet in the file has a placeholder instead of a version, so you must choose the tag yourself and remember that the current line is two majors past the example the README gives. The prerelease numbering is not usable as a version constraint, since two different snapshots both claim 605.0.0 with a date appended. And the Bazel support is labelled experimental by the project, with examples that pin 600.0.1 and 509.1.0 and one URL under the old apple organisation, so treat that path as unmaintained documentation. SwiftPM is the supported route. The licence is Apache-2.0.
Frequently asked questions
What is swift-syntax?
A set of Swift libraries that work on a source-accurate tree representation of Swift source code, called the SwiftSyntax tree. That tree forms the backbone of Swift's macro system, since macro expansion nodes are represented as SwiftSyntax nodes and a macro generates a SwiftSyntax tree to be inserted into the source file.
How do I add swift-syntax to a SwiftPM package?
Add a package dependency to `Package.swift` pointing at `https://github.com/swiftlang/swift-syntax.git`. The README's snippet leaves the version as the placeholder `<#latest swift-syntax tag#>`, so you have to fill in a tag yourself. Xcode users add it from the Package Dependencies tab by searching for the same URL.
How are swift-syntax releases versioned?
Releases are aligned with corresponding language and tooling releases, with the example given that major version 509 aligns with Swift 5.9. The recent releases are 604.0.0, a stable release, plus two date-stamped 605.0.0 prereleases from 2026-06-26 and 2026-09-15.
Does swift-syntax support Bazel?
There is an experimental Bazel build configuration maintained by Keith Smiley, with Bzlmod support from release 509.0.0. The recommended form is a `bazel_dep` entry and the alternative is an `http_archive` in `WORKSPACE`. Each library also has a `Library_opt` target that forces optimizations on, at the cost of debuggability and initial build time.
Where can I see a SwiftSyntax tree?
The documentation is published on swiftpackageindex.com, example usages live in the Examples directory of the repository, and an interactive explorer for the tree of a source file is available at swift-ast-explorer.com.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/swiftlang-swift-syntax)Star history chart for your README
[](https://hysenlabs.com/projects/swiftlang-swift-syntax)Was this useful?