AccessLint is a Swift accessibility linter that catches missing labels, undersized touch targets, and 23 other accessibility violations across SwiftUI and UIKit. This guide walks you through adding it to your GitHub Actions pipeline so new violations never reach production.

Prerequisites

  • An iOS project using SwiftUI, UIKit, or both
  • A GitHub repository with Actions enabled
  • An AccessLint license key (Team at $19.99/mo or Enterprise at $49.99/mo)

Step 1: Store Your License Key

Add your AccessLint license key as a GitHub Actions secret:

  1. Go to your repository on GitHub
  2. Navigate to Settings > Secrets and variables > Actions
  3. Click New repository secret
  4. Name it ACCESSLINT_LICENSE and paste your license key as the value

Step 2: Add the Workflow File

Create .github/workflows/accesslint.yml in your repository:

yaml
name: AccessLint

on:
  pull_request:
    paths:
      - '**/*.swift'

jobs:
  accessibility-lint:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run AccessLint
        uses: SyncTek-LLC/AccessLint@v1
        env:
          ACCESSLINT_LICENSE: ${{ secrets.ACCESSLINT_LICENSE }}

This minimal workflow runs AccessLint on every pull request that touches Swift files. If any finding at major severity or above is detected, the check fails.

Step 3: Configure Which Rules Run

Not every team needs all 25 rules from day one. Create an .accesslintrc.json config file at your project root to control which rules are active:

json
{
  "rules": {
    "enabled": [
      "A11Y.SWIFTUI.MISSING_LABEL",
      "A11Y.SWIFTUI.TOUCH_TARGET_SIZE",
      "A11Y.SWIFTUI.FIXED_FONT",
      "A11Y.SWIFTUI.REDUCE_MOTION",
      "A11Y.SWIFTUI.ORIENTATION_LOCK"
    ],
    "disabled": [
      "A11Y.SWIFTUI.IMAGE_DECORATIVE"
    ]
  }
}

When this file is present, AccessLint only enforces the rules listed under enabled. Without it, all 25 rules run by default. The full rule set covers missing labels, dynamic type support, touch target sizing, reduce motion respect, orientation lock, heading structure, and more -- the categories that cause the most real-world accessibility failures.

Step 4: Set Up Baseline Comparison

If you're adding AccessLint to an existing project, you probably have pre-existing violations you can't fix in one PR. Baseline mode lets you track existing issues separately so only new violations fail CI.

Generate your baseline locally first:

bash
$ brew tap synctek-llc/accesslint && brew install accesslint
$ accesslint analyze --format json --output .
$ cp accesslint-reports/findings.json .accesslint-baseline.json

Commit .accesslint-baseline.json to your repository. Then update your workflow to pass the baseline to the CLI:

yaml
name: AccessLint

on:
  pull_request:
    paths:
      - '**/*.swift'

jobs:
  accessibility-lint:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install AccessLint
        run: |
          brew tap synctek-llc/accesslint
          brew install accesslint

      - name: Run AccessLint with baseline
        run: accesslint analyze --path . --baseline .accesslint-baseline.json --fail-on major --format json
        env:
          ACCESSLINT_LICENSE: ${{ secrets.ACCESSLINT_LICENSE }}

With baseline mode active, existing violations are tracked but won't block your PRs. Any new violation introduced by the PR will still fail the check. As your team fixes baseline issues over time, regenerate the baseline file to shrink it.

Step 5: Fail CI on New Violations

The default behavior already fails on findings at major severity or above, but you can tune the threshold with the fail-on input. Valid values are blocker, major, minor, and info. The GitHub Action automatically generates JSON and Markdown reports and posts a PR comment:

yaml
name: AccessLint

on:
  pull_request:
    paths:
      - '**/*.swift'

jobs:
  accessibility-lint:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run AccessLint
        uses: SyncTek-LLC/AccessLint@v1
        with:
          path: .
          fail-on: major
        env:
          ACCESSLINT_LICENSE: ${{ secrets.ACCESSLINT_LICENSE }}

When fail-on is set to major (the default), any accessibility finding at major or blocker severity blocks the PR from merging. The action generates JSON and Markdown reports, posts a PR comment with findings, and integrates with GitHub Step Summary so developers see violations inline on the PR diff.

Complete Working Example

Here is a production-ready workflow combining everything above:

yaml
name: AccessLint CI

on:
  pull_request:
    paths:
      - '**/*.swift'
  push:
    branches: [main]

jobs:
  accessibility-lint:
    name: Accessibility Check
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run AccessLint
        uses: SyncTek-LLC/AccessLint@v1
        with:
          path: Sources/
          fail-on: major
        env:
          ACCESSLINT_LICENSE: ${{ secrets.ACCESSLINT_LICENSE }}

This runs on PRs and pushes to main, scans only the Sources/ directory, generates JSON and Markdown reports, posts a PR comment with findings, and blocks merges when new findings at major severity or above appear.

What Happens Next

Once this is live, your team gets immediate feedback on accessibility regressions. New code must pass all enabled rules before it can merge. Over time, chip away at the baseline until it's empty -- that's when your app is fully covered.

For local development, install the CLI directly so developers catch issues before pushing:

bash
$ brew tap synctek-llc/accesslint && brew install accesslint
$ accesslint analyze --path Sources/

That's it. Your CI pipeline now enforces accessibility standards on every pull request.

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