swiftlint — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited swiftlint (Agent Skill) and scored it 45/100 (orange). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 2 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 2 flagged
A base64 string of 128+ characters appears in a documentation file. Encoded prompt injection hides the hostile instruction in base64 — invisible to keyword filters — and relies on the agent's ability to decode it at runtime. There is no normal authoring reason to embed a multi-hundred-byte base64 blob in skill docs.
*.sig, SIGNATURES) outside the documentation.Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
SwiftLint enforces Swift style and conventions by linting source files against a configurable rule set. This skill covers setup, configuration, rule selection, suppression, CI integration, and rollout strategy.
SwiftLint is a style enforcement tool, not a style guide. For underlying Swift naming and design conventions, see swift-api-design-guidelines. For architecture patterns, see swift-architecture.
Default: build tool plugin via `SimplyDanny/SwiftLintPlugins`.
Add the plugin package to Package.swift or via Xcode's package dependencies:
// Package.swift
dependencies: [
.package(url: "https://github.com/SimplyDanny/SwiftLintPlugins", from: "<reviewed-version>")
]For SwiftPM targets, apply the plugin:
.target(
name: "MyApp",
plugins: [.plugin(name: "SwiftLintBuildToolPlugin", package: "SwiftLintPlugins")]
)For Xcode projects without a Package.swift, add the package dependency in the project settings, then enable the plugin under the target's Build Phases or the package's plugin trust dialog.
The build tool plugin runs SwiftLint automatically on every build. No run script required.
First build: Xcode prompts to trust the plugin. Select "Trust & Enable All" for the SwiftLintPlugins package.
For alternatives (run scripts, command plugin, Homebrew CLI), see references/plugins-run-scripts-and-integrations.md.
Create .swiftlint.yml at the project root. SwiftLint loads the main configuration from the invocation or plugin working directory, then can merge the nearest nested .swiftlint.yml for each file when configs are discovered automatically. Passing --config overrides automatic discovery and disables nested-config lookup.
# .swiftlint.yml — conservative starter config
disabled_rules:
- trailing_whitespace
- todo
opt_in_rules:
- empty_count
- closure_spacing
- force_unwrapping
- sorted_imports
- vertical_whitespace_opening_braces
- private_swiftui_state
- unhandled_throwing_task
- accessibility_label_for_image
included:
- Sources
- Tests
excluded:
- .build
- DerivedData
- "**/.build"
- "**/Generated"
line_length:
warning: 140
error: 200
type_body_length:
warning: 300
error: 500
file_length:
warning: 500
error: 1000Key configuration options:
| Key | Purpose |
|---|---|
disabled_rules | Turn off default-enabled rules |
opt_in_rules | Turn on rules not enabled by default |
only_rules | Use _only_ the listed rules (mutually exclusive with disabled_rules/opt_in_rules) |
analyzer_rules | Rules requiring compiler logs (run via swiftlint analyze) |
baseline | Path to an existing baseline file used to suppress known violations |
write_baseline | Path where SwiftLint should write a new baseline file |
included | Paths to lint (default: current directory) |
excluded | Paths to skip |
strict | Elevate all warnings to errors |
lenient | Downgrade all errors to warnings |
allow_zero_lintable_files | Suppress the error when no Swift files are found |
reporter | Output format: xcode (default), json, checkstyle, sarif, csv, emoji, etc. |
For full configuration details including severity tuning, environment-variable interpolation, and nested/remote configs, see references/adoption-and-configuration.md.
SwiftLint ships with three rule categories:
opt_in_rulesanalyzer_rulesBrowse the full categorized list at <https://realm.github.io/SwiftLint/rule-directory.html>.
Recommended approach for new projects:
swiftlint rules to see which rules are enabled.only_rules unless you have a specific reason to start from zero.Recommended approach for existing codebases:
Do not transcribe or memorize the rule directory. Look up rule identifiers and configuration options at the official rule directory when needed.
Suppress SwiftLint for specific lines when a rule produces a false positive or when the violation is intentional and reviewed.
// swiftlint:disable:next force_cast
let view = object as! UIView
let legacy = try! JSONDecoder().decode(T.self, from: data) // swiftlint:disable:this force_try
// swiftlint:disable:previous large_tupleDisable for a region:
// swiftlint:disable cyclomatic_complexity
func complexRouter(...) { ... }
// swiftlint:enable cyclomatic_complexityDisable all rules (use sparingly):
// swiftlint:disable all
// ... generated or legacy code ...
// swiftlint:enable allPolicy:
all.excluded paths in .swiftlint.yml over inline suppressions.For full suppression syntax, see references/rules-suppressions-and-baselines.md.
Baselines let you adopt SwiftLint in an existing codebase without fixing every legacy violation first.
Create a baseline:
swiftlint --write-baseline .swiftlint.baselineThis records all current violations. Future runs compare against this baseline and only report new violations.
Use the baseline:
swiftlint --baseline .swiftlint.baselineIn CI, pass --baseline so only new violations fail the build. Burn down the baseline over time by fixing legacy violations and regenerating.
For baseline workflows and rollout strategy, see references/rules-suppressions-and-baselines.md.
SwiftLint can fix some violations automatically:
swiftlint --fix
# or the legacy alias:
swiftlint --autocorrectWarnings:
--fix manually or in a dedicated CI step, then review the diff.swiftlint rules — the "Correctable" column shows which rules can auto-fix.--fix.CI is the primary enforcement surface. A CI check ensures no one merges code that increases the violation count.
Recommended CI pattern:
# GitHub Actions example
- name: Lint
run: |
brew install swiftlint
swiftlint --strict --reporter sarif > swiftlint.sarifKey CI options:
| Flag | Effect |
|---|---|
--strict | Exits non-zero on warnings (not just errors) |
--reporter sarif | GitHub Advanced Security compatible output |
--reporter json | Machine-readable output |
--reporter checkstyle | Jenkins/SonarQube compatible |
--baseline .swiftlint.baseline | Only fail on new violations |
For SARIF upload to GitHub code scanning, add github/codeql-action/upload-sarif after the lint step.
For full CI recipes and reporter details, see references/plugins-run-scripts-and-integrations.md.
Choose how to run SwiftLint based on project shape:
| Scenario | Recommended integration |
|---|---|
SwiftPM package or Xcode project with Package.swift | Build tool plugin via SwiftLintPlugins |
SwiftPM project needing CLI flags (--fix, --baseline) | Command plugin: swift package plugin swiftlint |
| Xcode project without SwiftPM, team uses Homebrew | Run script build phase |
| CI/CD pipeline | Homebrew or Docker install, run swiftlint directly |
| Pre-commit hook | Homebrew install + .pre-commit-config.yaml or git hook script |
The build tool plugin is preferred for local development because it requires no PATH configuration, pins the SwiftLint version via package resolution, and runs automatically on build.
For detailed setup instructions for each integration, see references/plugins-run-scripts-and-integrations.md.
SwiftLint supports layered configuration files. A .swiftlint.yml in a subdirectory inherits from and overrides the parent config.
Common patterns:
.swiftlint.yml in Tests/ that disables force_unwrapping and raises file_length.swiftlint.yml in a shared module directoryparent_config with an HTTPS URL to pull a shared team config (caching supported)# Tests/.swiftlint.yml — child config
disabled_rules:
- force_unwrapping
- force_try
file_length:
warning: 800You can also pass multiple configs on the CLI:
swiftlint --config .swiftlint.yml --config .swiftlint-extra.ymlLater configs override earlier ones for overlapping keys.
For nested config resolution, remote configs, and CLI multi-config details, see references/adoption-and-configuration.md.
--fix manually.disabled_rules + opt_in_rules instead.Brewfile / CI config.Tests/ entirely means test code gets no linting. Use a child config with relaxed rules instead.included, SwiftLint scans the working directory recursively, which may pick up vendored or generated code..swiftlint.yml exists at the project root with explicit included/excluded pathsswiftlint --strict (or with --baseline for incremental adoption)--fix / --autocorrect in build phasesall.swiftlint.yml deep dive, severity tuning, environment variables, nested/remote configs, rollout strategyswiftlint rules or the official rule directoryswiftlint analyze, compiler-log workflow~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.