A command-line tool to analyze Swift code complexity and quality metrics using swift-syntax.
- Multiple Complexity Metrics: Supports cyclomatic complexity, cognitive complexity, and LCOM4 cohesion analysis
- LCOM4 Class Cohesion: High-precision class cohesion measurement using IndexStore-DB semantic analysis
- Web-based Debug Interface: Interactive browser-based complexity analyzer (Try it online)
- Xcode Integration: Seamless integration with Xcode via Build Tool Plugin for complexity feedback during build phase
- Xcode Diagnostics: Display complexity warnings and errors directly in Xcode editor with accurate line numbers
- Configurable Thresholds: Set custom complexity thresholds via Xcode Build Settings or environment variables
- Per-Type Thresholds: Assign different thresholds to types by name (prefix/suffix) via a
.swift-complexity.ymlconfig — e.g. stricter limits for*Repository, looser for*UseCase - Inline Suppression: Exempt a specific function from threshold checks with a
// swift-complexity:disablecomment, optionally scoped to justcyclomaticorcognitive - Exit Code Integration: Returns exit code 1 when complexity thresholds are exceeded, perfect for CI/CD pipelines
- Multiple Output Formats: Text, JSON, XML, Xcode diagnostics, and SARIF output for different use cases
- Flexible Analysis: Single files, directories, or recursive directory analysis
- Swift Syntax Based: Uses
swift-syntaxfor accurate Swift code parsing - Cross-Platform Support: CLI works on macOS and Linux, library works on iOS 13+.
- MCP Server: Expose complexity analysis as tools for LLM agents (Claude Code, etc.) via Model Context Protocol
- Claude Plugin: Ready-to-use Claude Code plugin with MCP server and analysis skill
- Extensible Architecture: Designed to support additional quality metrics in the future
Visit swift-complexity.fummicc1.dev to analyze Swift code instantly in your browser.
On macOS the recommended path is Homebrew:
brew install fummicc1/tap/swift-complexityOr build from source:
git clone https://github.com/fummicc1/swift-complexity
cd swift-complexity
swift build -c releasePre-built binaries are also available from GitHub Releases as Swift Artifact Bundles, or via nest install fummicc1/swift-complexity.
# Analyze a single file
swift run SwiftComplexityCLI path/to/file.swift
# Analyze a directory with threshold enforcement
swift run SwiftComplexityCLI Sources --threshold 10
# JSON output for tooling integration
swift run SwiftComplexityCLI Sources --format json --recursive
# Xcode diagnostics format (for IDE integration)
swift run SwiftComplexityCLI Sources --format xcode --threshold 15
# SARIF format (for GitHub Code Scanning)
swift run SwiftComplexityCLI Sources --format sarif --threshold 10 --recursive > swift-complexity.sarif
# LCOM4 class cohesion analysis (requires swift build first)
swift build # Generate index
swift run SwiftComplexityCLI Sources --lcom4 --index-store-path .build/debug/index/storeThe tool returns exit code 1 when any function exceeds the specified complexity threshold, making it ideal for:
- CI/CD Pipelines: Fail builds when complexity thresholds are exceeded
- Git Hooks: Prevent commits with overly complex code
- Code Quality Gates: Enforce complexity standards across teams
# Example: Fail if any function has complexity > 15
swift run SwiftComplexityCLI Sources --threshold 15 --recursive
# Exit code 0: All functions below threshold
# Exit code 1: One or more functions exceed thresholdAssign different thresholds per nominal type (class/struct/enum/actor and extensions)
so each layer or feature gets its own complexity budget. Create a
.swift-complexity.yml (auto-discovered in the current directory, or pass --config <path>):
# .swift-complexity.yml
defaultThreshold: 10 # Fallback for types matching no rule (optional)
rules:
- prefix: Toilet # Feature grouping (type name prefix)
threshold: 12
- suffix: Repository # Layer grouping (type name suffix)
threshold: 5
- suffix: UseCase
threshold: 15A function's threshold is resolved from its enclosing type name: among all matching
rules the strictest (lowest) wins (e.g. ToiletRepository matches Toilet=12 and
Repository=5 → 5). Unmatched types fall back to --threshold or defaultThreshold.
# Auto-discovers .swift-complexity.yml
swift run SwiftComplexityCLI Sources --recursive
# Explicit config path
swift run SwiftComplexityCLI Sources --recursive --config config/complexity.ymlExempt a single, reviewed function from threshold checks with a comment directly above its declaration. There is no "next line" form and no "enable" comment — the directive always applies to exactly the one declaration it precedes.
// swift-complexity:disable
func parseLegacyFormat(_ input: String) -> Document { ... }
// swift-complexity:disable cognitive
func stateMachine(_ event: Event) { ... } // cyclomatic is still checkedSuppressed values are still computed and shown in every output format — only the
threshold judgment is skipped. Run with --report-suppressions to print every
suppressed function and its current values to stderr, so suppressions stay
visible instead of silently hiding violations. See the
usage guide for the
full syntax, including why an unrecognized metric name suppresses nothing
rather than everything.
See the Usage Guide for full resolution rules.
- Cyclomatic Complexity: Measures the number of linearly independent paths through code
- Cognitive Complexity: Measures how difficult code is for humans to understand
- LCOM4 (Lack of Cohesion of Methods): Measures class cohesion by analyzing method-property relationships
- Connected Components: Counts independent groups of related methods
- High Precision: Semantic analysis powered by IndexStore-DB
- Implicit self Detection: Automatically detects both
self.propertyandpropertyaccesses - Requirements: Requires
swift buildto generate index data
- User Guide: Installation, usage, and examples
- Complexity Metrics: Detailed metric explanations and examples
- Output Formats: Text, JSON, XML, Xcode diagnostics, and SARIF format specifications
- Development Guide: Setup for contributors
- Debug Website: Web-based interactive analyzer documentation
Unified package with multiple components:
- SwiftComplexityCore: Core analysis library (supports macOS 14+, iOS 13+)
- SwiftComplexityCLI: Command-line interface
- SwiftComplexityMCP: MCP server for LLM agent integration
- SwiftComplexityPlugin: Xcode Build Tool Plugin
- Frontend: Next.js application deployed on Cloudflare Workers
- Backend: Vapor 4 API containerized on Cloudflare Containers.
- Live Demo: swift-complexity.fummicc1.dev
# Analyze with verbose output
swift run SwiftComplexityCLI Sources --verbose --recursive
# Exclude test files with pattern matching
swift run SwiftComplexityCLI Sources --recursive --exclude "*Test*.swift"
# Show only cognitive complexity above threshold
swift run SwiftComplexityCLI Sources --cognitive-only --threshold 5
# Analyze class cohesion with LCOM4
swift build # Generate index first
swift run SwiftComplexityCLI Sources --lcom4 --index-store-path .build/debug/index/store --format jsonThe MCP (Model Context Protocol) server exposes complexity analysis as tools for LLM agents like Claude Code.
# Homebrew (macOS, recommended)
brew install fummicc1/tap/swift-complexity-mcp
# Mint: MCP server only
mint install fummicc1/swift-complexity SwiftComplexityMCP
# Mint: both CLI and MCP server at once
mint install fummicc1/swift-complexity| Tool | Description |
|---|---|
analyze_complexity |
Analyze Swift files/directories on disk (recursive, threshold, per-type thresholds via config_path, LCOM4 support) |
analyze_code_string |
Analyze a Swift code string directly without files on disk |
Claude Code (settings.json):
{
"mcpServers": {
"swift-complexity": {
"command": "SwiftComplexityMCP"
}
}
}Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"swift-complexity": {
"command": "SwiftComplexityMCP"
}
}
}A ready-to-use Claude Code plugin is available in claude-plugin/.
Prerequisite: The plugin requires SwiftComplexityMCP binary in your PATH. Install via Mint first:
mint install fummicc1/swift-complexity SwiftComplexityMCPThen load the plugin:
# Load the plugin
claude --plugin-dir ./claude-plugin
# Use the skill
/swift-complexity:analyze-complexityThe plugin bundles the MCP server configuration and an analyze-complexity skill that guides Claude through complexity analysis workflows.
Integrates with both Swift Package Manager and Xcode projects for automatic complexity analysis during builds.
// swift-tools-version: 6.2
import PackageDescription
let package = Package(
name: "YourProject",
dependencies: [
.package(url: "https://github.com/fummicc1/swift-complexity.git", from: "1.0.0")
],
targets: [
.target(
name: "YourTarget",
plugins: [
.plugin(name: "SwiftComplexityPlugin", package: "swift-complexity")
]
)
]
)- Add swift-complexity package to your Xcode project
- In Build Phases, add "SwiftComplexityPlugin" to Run Build Tool Plug-ins
- Configure threshold in Build Settings (optional)
Xcode Build Settings:
- Key:
SWIFT_COMPLEXITY_THRESHOLD - Value:
15(or any number, defaults to 10)
Environment Variable (SPM):
SWIFT_COMPLEXITY_THRESHOLD=15
- Real-time feedback: Complexity warnings appear directly in Xcode editor
- Accurate positioning: Errors show at exact function locations
- Build integration: Builds fail when thresholds are exceeded
- Configurable per target: Different thresholds for different modules
File: Sources/ComplexityAnalyzer.swift
+------------------+----------+----------+
| Function/Method | Cyclo. | Cogn. |
+------------------+----------+----------+
| analyzeFunction | 3 | 2 |
| calculateTotal | 5 | 7 |
+------------------+----------+----------+
Total: 2 functions, Average Cyclomatic: 4.0, Average Cognitive: 4.5
Class Cohesion (LCOM4):
+--------------------+----------+----------+----------+----------+
| Class/Struct | LCOM4 | Methods | Props | Level |
+--------------------+----------+----------+----------+----------+
| ComplexityAnalyzer | 1 | 5 | 3 | High |
| FileProcessor | 2 | 8 | 4 | Moderate |
+--------------------+----------+----------+----------+----------+
/path/to/Sources/MyFile.swift:45:1: error: Function 'complexFunction' has high complexity (Cyclomatic: 15, Cognitive: 23, Threshold: 10)
/path/to/Sources/MyFile.swift:89:1: warning: Function 'anotherFunction' has high complexity (Cyclomatic: 12, Cognitive: 18, Threshold: 10)
Generate a SARIF report and upload it to GitHub Code Scanning to get complexity violations as inline pull request annotations:
- name: Analyze complexity
run: swift-complexity Sources --format sarif --threshold 10 --recursive > swift-complexity.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: swift-complexity.sarifViolations are reported per metric (cyclomatic_complexity, cognitive_complexity,
and lcom4_cohesion) with warning level, escalating to error at twice the threshold.
- Swift 6.2+
- macOS 14+ or Linux
- Swift 6.2+
- macOS 14+, iOS 13+, or Linux
- macOS 14+: Xcode toolchain is auto-detected
- Linux: Requires
--toolchain-pathoption pointing to Swift toolchain - Project must be buildable with
swift build - Index data at
.build/debug/index/store(generated by build)
Linux Example:
# Using Swiftly-installed toolchain
TOOLCHAIN=~/.local/share/swiftly/toolchains/swift-6.2.2-RELEASE
swift build \
-Xcxx -I${TOOLCHAIN}/usr/lib/swift \
-Xcxx -I${TOOLCHAIN}/usr/lib/swift/Block
.build/debug/SwiftComplexityCLI Sources --lcom4 \
--index-store-path .build/debug/index/store \
--toolchain-path ${TOOLCHAIN}MIT License

