AccessLint is a Swift accessibility linter that catches missing labels, undersized touch targets, fixed fonts, and more across SwiftUI and UIKit codebases. This guide walks you through installing AccessLint, wiring it into Xcode so violations surface during every build, and setting up pre-commit hooks so problems never reach your remote branch.

Install AccessLint

AccessLint ships via Homebrew. Add the tap and install:

bash
$ brew tap synctek-llc/accesslint
$ brew install accesslint

Set your license key (Team $19.99/mo, Enterprise $49.99/mo) so the full 25-rule set is active:

bash
$ export ACCESSLINT_LICENSE="your-license-key"

Add that export to your ~/.zshrc or ~/.bash_profile so it persists across terminal sessions.

Verify the install:

bash
$ accesslint analyze --help

Add AccessLint as an Xcode Build Phase

This is the fastest way to get real-time feedback. Every time you build, AccessLint scans your source and reports violations inline.

  1. Open your project in Xcode.
  2. Select your app target, then go to Build Phases.
  3. Click the + button and choose New Run Script Phase.
  4. Name it "AccessLint Analyze" and drag it above Compile Sources so it runs early.
  5. Paste the following script:
bash
if which accesslint > /dev/null; then
  accesslint analyze "${SRCROOT}/Sources" --fail-on major
else
  echo "warning: AccessLint not installed. Run: brew tap synctek-llc/accesslint && brew install accesslint"
fi

Because accesslint analyze exits with code 1 when violations are found, Xcode treats the build phase as a failure and stops the build. This means accessibility regressions block compilation the same way a syntax error would.

To scan all severities (warnings included) without blocking the build, remove --fail-on major and uncheck "Based on dependency analysis" in the build phase settings.

Interpret the Results

AccessLint output appears in the Xcode build log and in your terminal when you run scans manually. Each violation follows this format:

Sources/LoginView.swift:42: error: [BUTTON_MISSING_LABEL] Button has no accessibility label (severity: error)
Sources/ProfileView.swift:18: warning: [DYNAMIC_TYPE_FONT_USED] Use Dynamic Type fonts for scalable text (severity: warning)
Sources/MapView.swift:91: warning: [TOUCH_TARGET_SIZE] Touch target is smaller than 44x44pt (severity: warning)

Each line gives you the file, line number, rule ID, severity, and a human-readable description. The 25 built-in rules cover the areas that matter most: BUTTON_MISSING_LABEL, DYNAMIC_TYPE_FONT_USED, TOUCH_TARGET_SIZE, REDUCE_MOTION, ORIENTATION_LOCK, color contrast ratios, and more.

For CI pipelines or scripted processing, use JSON output:

bash
$ accesslint analyze Sources/ --format json

Set Up a Pre-Commit Hook

A pre-commit hook catches violations before code leaves your machine. Create .git/hooks/pre-commit (or add to your existing hook):

bash
#!/usr/bin/env bash
set -euo pipefail

STAGED_SWIFT=$(git diff --cached --name-only --diff-filter=ACM -- '*.swift')

if [ -z "$STAGED_SWIFT" ]; then
  exit 0
fi

echo "Running AccessLint on staged Swift files..."

# Write staged files to a temp dir to scan only what's being committed
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT

for file in $STAGED_SWIFT; do
  mkdir -p "$TMPDIR/$(dirname "$file")"
  git show ":$file" > "$TMPDIR/$file"
done

accesslint analyze "$TMPDIR" --fail-on major

echo "AccessLint passed."

Make it executable:

bash
$ chmod +x .git/hooks/pre-commit

If your team uses a hooks manager like Lefthook or Husky, add the accesslint analyze command to your existing configuration instead.

Configure Rules and Suppress False Positives

To run only a subset of rules, pass --fail-on major to limit failures to major issues, or use the --format json flag and filter by rule ID in a wrapper script.

To suppress a specific violation inline, add a comment directly above the flagged line:

swift
// accesslint:disable TOUCH_TARGET_SIZE
Button(action: toggle) {
    Image(systemName: "info.circle")
}

To disable a rule project-wide, create an .accesslint.yaml file in your project root:

yaml
rules:
  ORIENTATION_LOCK: off
  REDUCE_MOTION: warning   # downgrade from error to warning

This lets you roll out AccessLint incrementally -- start with the highest-impact rules, fix those, then enable the rest.

What's Next

With AccessLint in your build phase and pre-commit hook, accessibility violations get the same treatment as compiler errors: they surface immediately and block bad code from shipping. Run accesslint analyze across your full project once to get a baseline, fix the errors, then let the automation keep you honest going forward.

Ready to try AccessLint?

Install the CLI and catch your first accessibility violation in under two minutes. Free tier includes 10 rules.

Get Started Free