How to Install SwiftLint and Add It as an Xcode Build Phase

A practical, step-by-step guide to installing SwiftLint and wiring it into Xcode so style violations appear as warnings right in your build, including Apple Silicon path gotchas.

What You'll Accomplish

By the end of this guide, SwiftLint will run automatically every time you build in Xcode, and any style violations will show up as warnings in the issue navigator next to your compiler messages.

This is the most common way iOS developers use SwiftLint, because it puts feedback exactly where you already look. You do not have to remember to run anything manually.

We will cover installing the tool, adding a run-script build phase, and handling the path differences that trip up developers on Apple Silicon Macs.

Nothing here changes how your app builds or ships. SwiftLint only inspects Swift source and reports on it; Xcode still does the actual compiling and signing.

Prerequisites

You need a Mac with Xcode installed and an existing iOS project or Swift package to lint. SwiftLint analyzes Swift files, so any Swift target will do.

The simplest way to install SwiftLint is with Homebrew, the popular macOS package manager. If you do not already have Homebrew, install it first from its official site.

You should be comfortable opening Terminal and running a command or two. Everything else happens inside Xcode's graphical interface.

Finally, decide whether you want SwiftLint installed globally on your machine via Homebrew, or pinned per-project. This guide starts with the global Homebrew approach because it is the fastest path to a working setup.

Step 1: Install SwiftLint with Homebrew

Open Terminal and run the Homebrew install command for SwiftLint:

`brew install swiftlint`

Homebrew will download and install the tool along with any dependencies. When it finishes, verify the installation by asking for the version:

`swiftlint version`

If you see a version number printed, SwiftLint is installed and on your PATH. If instead you get a "command not found" message, your shell may not have Homebrew's binary directory on its PATH yet — close and reopen Terminal, or follow Homebrew's post-install instructions.

Make a mental note of where the binary lives. On Apple Silicon Macs, Homebrew installs to `/opt/homebrew/bin`, while on older Intel Macs it uses `/usr/local/bin`. This distinction matters in the next steps.

Step 2: Try a Manual Lint Run

Before touching Xcode, confirm SwiftLint can actually read your project. In Terminal, change into your project's root directory — the folder that contains your `.xcodeproj` or `Package.swift`.

Run the linter with no arguments:

`swiftlint`

SwiftLint will scan the Swift files it finds and print any violations, each with a file path, line number, and a short description of the rule that was broken.

Seeing output here — even a long list of warnings — is a good sign. It means the tool is working and your project is discoverable. If you get zero output and no errors, your code may already be clean, or you may be in the wrong directory.

This manual run is also the fastest way to sanity-check any configuration you add later.

Step 3: Add the Run-Script Build Phase

Now wire SwiftLint into Xcode. Open your project, select the project in the navigator, then select your app target.

Go to the Build Phases tab. Click the plus button in the top-left of that pane and choose New Run Script Phase. A new, empty script phase appears at the bottom of the list.

Expand it and paste a script that checks whether SwiftLint exists and runs it. A robust version handles Apple Silicon and Intel paths:

`if [ -x "/opt/homebrew/bin/swiftlint" ]; then /opt/homebrew/bin/swiftlint; elif [ -x "/usr/local/bin/swiftlint" ]; then /usr/local/bin/swiftlint; else echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"; fi`

Using the explicit paths avoids the single most common setup failure, where the build phase runs in an environment that does not have Homebrew on its PATH. The final `else` branch prints a friendly warning instead of failing silently.

Step 4: Position and Name the Phase

Order matters a little. Drag the new run-script phase so it runs early — a common choice is right after Dependencies and before Compile Sources — so you see lint feedback promptly.

Give the phase a clear name by double-clicking its title, such as "Run SwiftLint." Future you, and your teammates, will appreciate not seeing a generic "Run Script" entry.

If your Xcode version offers an option to run the script based on dependency analysis or for install builds only, leave the defaults unless you have a specific reason to change them. For most projects the standard behavior is fine.

Save, then build the project with Command-B.

Step 5: Verify Violations Appear in Xcode

After the build completes, open the issue navigator with Command-5. SwiftLint violations appear there as yellow warnings, each linked to the exact line in your source.

Click one. Xcode jumps to the offending line, and the warning text tells you which rule fired. This is the payoff — style feedback living in the same place as compiler diagnostics.

If you see nothing at all, first confirm the build actually ran the script by checking the build log. If you see a "SwiftLint not installed" warning, revisit the paths in Step 3, since your Homebrew location may differ.

Note that on recent Xcode versions you may hit a sandboxing restriction that blocks the script from reading files. If that happens, that is a known, fixable issue covered in our dedicated troubleshooting guide.

Optional: Pin SwiftLint Per Project

Global Homebrew installs are convenient, but different projects may need different SwiftLint versions, and teammates may drift out of sync. For serious teams, pinning the version per project is worth it.

One common approach is to declare SwiftLint as a dependency of a Swift package tool or plugin, so everyone on the team resolves the exact same version through the project itself. Another is to use a version manager that reads a pinned version file.

Whichever you choose, commit the configuration so a fresh checkout produces the same lint results on every machine and in CI. Consistency between local builds and CI is the whole point.

Start with the global install to get going today, then graduate to a pinned setup once the team grows. Both approaches use the same build-phase script pattern shown above.

What This Does Not Do

Adding SwiftLint as a build phase gives you fast, automatic style feedback, but keep its scope in mind. It does not compile, sign, or ship your app — Xcode still does all of that, and releasing to the App Store still requires an Apple Developer Program membership.

It also will not enforce anything until you decide which rules matter. The next natural step is creating a configuration file to tune rules to your team's taste.

And it does not replace tests or code review. Think of it as an always-on style reviewer that never gets tired, sitting alongside the rest of your quality process.

With installation done, you now have SwiftLint running on every build. From here, configuration is where you make it truly yours.

Frequently Asked Questions

Do I have to use Homebrew to install SwiftLint?

No, but it is the easiest path on macOS. You can also install SwiftLint through other package or version managers, or pin it per project via a Swift package plugin. Homebrew simply gets you running fastest.

Why does my build phase say SwiftLint is not installed even though I installed it?

The build phase runs in an environment that may not include Homebrew on its PATH, especially on Apple Silicon. Reference the full binary path such as /opt/homebrew/bin/swiftlint in your script to fix this.

Should the SwiftLint phase run before or after Compile Sources?

A common choice is to run it early, right after Dependencies and before Compile Sources, so you get style feedback quickly. The exact position rarely matters for correctness.

Will SwiftLint warnings block my build?

By default violations appear as warnings and do not stop the build. You can configure certain rules to be errors if you want them to fail the build instead.