Formatting technology for Swift source code

What's New



What's Changed

  • Update to non-optional leading/trailingTrivia swift-syntax API by @bnbarham in #497
  • Adjustments to split FunctionParameterSyntax into multiple nodes for function parameters, closure parameters and enum parameters by @ahoppen in #495
  • Prepare 508.0.0 release. by @allevato in #506
  • Fix formatting of import with multiple attributes (fixes #445) and ensure that imports never wrap by @stackotter in #501
  • Fix fatal error caused by switch cases without any statements (#473) by @stackotter in #499
  • Remove the swift-tools-support-core dependency from swift-format. by @allevato in #509
  • Fix pretty printing of multi-statement closures (issue #494) by @stackotter in #498
  • Avoid removing certain disambiguating parens from conditions (fixes #298) by @stackotter in #503
  • Fix more postfix pound if scenarios by @DavidBrunow in #402
  • Remove usages of functions that shouldn’t be part of SwiftSyntax’s public API by @ahoppen in #504
  • Removed warnings by @CippoX in #510
  • Adjustment for SwiftSyntax rename members -> memberBlock by @ahoppen in #512
  • [SwiftSyntax] Remove force unwrapping for source location by @kimdv in #513
  • Change version dependency on swift-argument-parser to from upToNextMinor to upToNextMajor by @ahoppen in #517
  • Replace deprecated code of swift-syntax with the latest code to remove warning by @TTOzzi in #531
  • Fix indentation of multiline strings when part of a larger expression. by @allevato in #532
  • Fix try/await expressions in NoAssignmentInExpressions. by @allevato in #533
  • Further improve multiline string formatting. by @allevato in #534
  • Allow exceptions to NoAssignmentInExpressions. by @allevato in #535
  • Add Token.break after fixity in operator declaration by @StevenWong12 in #536
  • Rename elementList in TupleExprSyntax to elements by @StevenWong12 in #537
  • Fix async throws function types when they appear in an expression context. by @allevato in #539
  • Replace deprecated code from swift-syntax by @TTOzzi in #540
  • Wrap keypath literals appropriately. by @allevato in #545
  • Format macro declarations. by @allevato in #546
  • Insert white space before trailing closure of a macro expression by @kimberninger in #544
  • Rename 'squareBracket' to 'square' by @TTOzzi in #541
  • Delete UnknownNodeTests. by @allevato in #548
  • Fix formatting of @backDeploy attribute. by @allevato in #550
  • Don't insert an extra break inside empty multiline strings. by @allevato in #551
  • Downgrade editor placeholder in source file from error to warning. by @allevato in #547
  • Improve wrapping of if/switch expressions. by @allevato in #553
  • Fix postfix-#if formatting when they come after a closing parenthesis. by @allevato in #554
  • Fix indentation of multiline strings in enum case raw values. by @allevato in #555
  • Fix deprecated SwiftSyntax api warnings by @kitasuke in #558
  • Remove the compiler condition guarding DerivativeRegistrationAttributeArgumentsSyntax. by @allevato in #559
  • Use swift-markdown to parse documentation comments. by @allevato in #560
  • Adjustment because of a property rename in swift-syntax by @ahoppen in #561
  • Replace [TriviaPiece].Index with Array<TriviaPiece>.Index. by @allevato in #565
  • Remove --mode flag for configuration dump by @Gray-Wind in #566
  • Use newer equivalents of deprecated nodes names by @Matejkob in #567
  • Add XCTest exclusion comment for lint rules by @kitasuke in #568
  • Use methods on Sequence instead of SyntaxCollection by @kitasuke in #569
  • Update swift-format for renamed children in SwiftSyntax by @ahoppen in #562
  • Fix deprecated warnings regarding swift-syntax changes by @kitasuke in #570
  • Adjustments for node renames in swift-syntax by @ahoppen in #572
  • Remove initializer from TupleTypeElementSyntax initializer call by @ahoppen in #573
  • Rename children of differentiability nodes by @ahoppen in #574
  • Adjustments for refactoring of representation of Accessors in SwiftSyntax by @ahoppen in #576
  • Use where instead of filter for for loops by @ahoppen in #575
  • Adjustments for usage of DeclReferenceExprSyntax as child of MemberAccessExprSyntax by @ahoppen in #577
  • [Core] Add new finding severity kinds - refactoring and convention by @xedin in #578
  • Fix deprecation warnings from renamed nodes / types in SwiftSyntax by @ahoppen in #579
  • Move the default Configuration.init() into a separate file. by @allevato in #580
  • Don't alter doc line comments unnecessarily. by @allevato in #581
  • Improve a bunch of diagnostic messages. by @allevato in #583
  • Migrate away from the latest deprecated APIs. by @allevato in #584
  • Replace the ReplaceTrivia rewriter with direct trivia mutations. by @allevato in #588
  • Parenthesize some/any types when converting Optional to ?. by @allevato in #589
  • Update for the fact that syntax collections are always non-optional in SwiftSyntax now by @ahoppen in #585
  • Make shebang a child of SourceFileSyntax by @StevenWong12 in #590
  • [Lint] Add a rule to detect that type declarations are not capitalized by @xedin in #587
  • Don't warn about a redundant synthesized memberwise init if it has attributes. by @allevato in #592
  • Collapse almost everything into a single SwiftFormat module. by @allevato in #593
  • Refactor tests. by @allevato in #595
  • Don't do anything if the input is empty. by @allevato in #599
  • Fix a bunch of FIXMEs around linter findings. by @allevato in #597
  • [Lint/Format] Add a rule to omit return from functions, closures, subscripts, and variables by @xedin in #596
  • [Lint] Add a rule to replace .forEach with a for-in loop by @xedin in #603
  • Replace with calls with in-place mutation; clean up helpers. by @allevato in #609
  • Actually implement NoPlaygroundLiterals rule. by @allevato in #613
  • Adjust for "remark" diagnostic severity by @DougGregor in #605
  • Move Configuration into the SwiftFormat module. by @allevato in #614
  • Fix invalid links in README by @woxtu in #594
  • Default to all targets when plugin --target parameter missing. Fix #483 by @BrianHenryIE in #608
  • Remove unnecessary casting by @Matejkob in #618
  • Output a warning for unknown configuration rules in .swift-format by @natikgadzhi in #612
  • Generate rule docs automatically by @natikgadzhi in #615
  • [5.10] Add fixes that were present in 509.0.0 but not release/5.10 by @ahoppen in #704

New Contributors


swift-format provides the formatting technology for SourceKit-LSP and the building blocks for doing code formatting transformations.

This package can be used as a command line tool or linked into other applications as a Swift Package Manager dependency and invoked via an API.

NOTE: No default Swift code style guidelines have yet been proposed. The style that is currently applied by swift-format is just one possibility, and the code is provided so that it can be tested on real-world code and experiments can be made by modifying it.

Matching swift-format to Your Swift Version

Swift 5.8 and later

As of Swift 5.8, swift-format depends on the version of SwiftSyntax whose parser has been rewritten in Swift and no longer has dependencies on libraries in the Swift toolchain.

This change allows swift-format to be built, developed, and run using any version of Swift that can compile it, decoupling it from the version that supported a particular syntax. However, earlier versions of swift-format will still not be able to recognize new syntax added in later versions of the language and parser.

Note also that the version numbering scheme has changed to match SwiftSyntax; the 5.8 release of swift-format is 508.0.0, not 0.50800.0.

Swift 5.7 and earlier

swift-format versions 0.50700.0 and earlier depend on versions of SwiftSyntax that used a standalone parsing library distributed as part of the Swift toolchain. When using these versions, you should check out and build swift-format from the release tag or branch that is compatible with the version of Swift you are using.

The major and minor version components of swift-format and SwiftSyntax must be the same—this is expressed in the SwiftSyntax dependency in Package.swift—and those version components must match the Swift toolchain that is installed and used to build and run the formatter:

Xcode Release Swift Version swift-format Branch / Tags
Swift at main main
Xcode 14.0 Swift 5.7 release/5.7 / 0.50700.x
Xcode 13.3 Swift 5.6 release/5.6 / 0.50600.x
Xcode 13.0–13.2 Swift 5.5 swift-5.5-branch / 0.50500.x
Xcode 12.5 Swift 5.4 swift-5.4-branch / 0.50400.x
Xcode 12.0–12.4 Swift 5.3 swift-5.3-branch / 0.50300.x
Xcode 11.4–11.7 Swift 5.2 swift-5.2-branch / 0.50200.x
Xcode 11.0–11.3 Swift 5.1 swift-5.1-branch

For example, if you are using Xcode 13.3 (Swift 5.6), you will need swift-format 0.50600.0.

Getting swift-format

If you are mainly interested in using swift-format (rather than developing it), then once you have identified the version you need, you can check out the source and build it using the following commands:

VERSION=508.0.0  # replace this with the version you need
git clone https://github.com/apple/swift-format.git
cd swift-format
git checkout "tags/$VERSION"
swift build -c release

Note that the git checkout command above will leave the repository in a "detached HEAD" state. This is fine if building and running the tool is all you want to do.

Once the build has finished, the swift-format executable will be located at .build/release/swift-format.

To test that the formatter was built successfully and is compatible with your Swift toolchain, you can also run the following command:

swift test --parallel

We recommend using the --parallel flag to speed up the test run since there are a large number of tests.

Command Line Usage

The general invocation syntax for swift-format is as follows:

swift-format [SUBCOMMAND] [OPTIONS...] [FILES...]

The tool supports a number of subcommands, each of which has its own options and are described below. Descriptions of the subcommands that are available can also be obtained by running swift-format --help, and the description of a specific subcommand can be obtained by using the --help flag after the subcommand name; for example, swift-format lint --help.


swift-format [format] [OPTIONS...] [FILES...]

The format subcommand formats one or more Swift source files (or source code from standard input if no file paths are given on the command line). Writing out the format subcommand is optional; it is the default behavior if no other subcommand is given.

This subcommand supports all of the common lint and format options, as well as the formatting-only options below:

  • -i/--in-place: Overwrites the input files when formatting instead of printing the results to standard output. No backup of the original file is made before it is overwritten.


swift-format lint [OPTIONS...] [FILES...]

The lint subcommand checks one or more Swift source files (or source code from standard input if no file paths are given on the command line) for style violations and prints diagnostics to standard error for any violations that are detected.

This subcommand supports all of the common lint and format options, as well as the linting-only options below:

  • -s/--strict: If this option is specified, lint warnings will cause the tool to exit with a non-zero exit code (failure). By default, lint warnings do not prevent a successful exit; only fatal errors (for example, trying to lint a file that does not exist) cause the tool to exit unsuccessfully.

Options Supported by Formatting and Linting

The following options are supported by both the format and lint subcommands:

  • --assume-filename <path>: The file path that should be used in diagnostics when linting or formatting from standard input. If this option is not provided, then <stdin> will be used as the filename printed in diagnostics.

  • --color-diagnostics/--no-color-diagnostics: By default, swift-format will print diagnostics in color if standard error is connected to a terminal and without color otherwise (for example, if standard error is being redirected to a file). These flags can be used to force colors on or off respectively, regardless of whether the output is going to a terminal.

  • --configuration <file>: The path to a JSON file that contains configurable settings for swift-format. If omitted, a default configuration is use (which can be seen by running swift-format dump-configuration).

  • --ignore-unparsable-files: If this option is specified and a source file contains syntax errors or can otherwise not be parsed successfully by the Swift syntax parser, it will be ignored (no diagnostics will be emitted and it will not be formatted). Without this option, an error will be emitted for any unparsable files.

  • -p/--parallel: Process files in parallel, simultaneously across multiple cores.

  • -r/--recursive: If specified, then the tool will process .swift source files in any directories listed on the command line and their descendants. Without this flag, it is an error to list a directory on the command line.

Viewing the Default Configuration

swift-format dump-configuration

The dump-configuration subcommand dumps the default configuration in JSON format to standard output. This can be used to simplify generating a custom configuration, by redirecting it to a file and editing it.

Configuring the Command Line Tool

For any source file being checked or formatted, swift-format looks for a JSON-formatted file named .swift-format in the same directory. If one is found, then that file is loaded to determine the tool's configuration. If the file is not found, then it looks in the parent directory, and so on.

If no configuration file is found, a default configuration is used. The settings in the default configuration can be viewed by running swift-format dump-configuration, which will dump it to standard output.

If the --configuration <file> option is passed to swift-format, then that configuration will be used unconditionally and the file system will not be searched.

See Documentation/Configuration.md for a description of the configuration file format and the settings that are available.


Running swift-format -v or swift-format --version will print version information about swift-format version and then exit.

API Usage

swift-format can be easily integrated into other tools written in Swift. Instead of invoking the formatter by spawning a subprocess, users can depend on swift-format as a Swift Package Manager dependency and import the SwiftFormat module, which contains the entry points into the formatter's diagnostic and correction behavior.

Formatting behavior is provided by the SwiftFormatter class and linting behavior is provided by the SwiftLinter class. These APIs can be passed either a Swift source file URL or a Syntax node representing a SwiftSyntax syntax tree. The latter capability is particularly useful for writing code generators, since it significantly reduces the amount of trivia that the generator needs to be concerned about adding to the syntax nodes it creates. Instead, it can pass the in-memory syntax tree to the SwiftFormat API and receive perfectly formatted code as output.

Please see the documentation in the SwiftFormatter and SwiftLinter classes for more information about their usage.

Checking Out the Source Code for Development

The main branch is used for development. Pull requests should be created to merge into the main branch; changes that are low-risk and compatible with the latest release branch may be cherry-picked into that branch after they have been merged into main.

If you are interested in developing swift-format, there is additional documentation about that here.


  • Swift Tools 5.6.0
View More Packages from this Author


Last updated: Fri Jun 14 2024 21:05:32 GMT-0900 (Hawaii-Aleutian Daylight Time)