Introduction
Periphery scans Swift projects to find declarations that are never referenced. Unlike simple grep-based tools, it builds the full project with the Swift compiler and analyzes the indexed symbol graph, so its results account for protocol conformances, dynamic dispatch, and cross-module references.
What Periphery Does
- Identifies unused classes, structs, enums, functions, properties, and type aliases
- Detects unused protocol conformances and protocol declarations with no adopters
- Finds redundant public access control where internal would suffice
- Scans Objective-C bridging headers for unused @objc-exposed declarations
- Reports unused import statements that add compile-time overhead
Architecture Overview
Periphery invokes xcodebuild or swift build to compile the project and produce a full index store — the same database Xcode uses for jump-to-definition. It then walks the index store's symbol graph to determine which declarations are referenced and which are not. This compiler-backed approach means it understands generics, protocol extensions, and conditional compilation blocks correctly.
Self-Hosting & Configuration
- Install via Homebrew or download the binary from GitHub releases
- Run periphery scan --setup on first use to select targets and build configuration
- Use a .periphery.yml config file to persist scan settings and exclusion patterns
- Exclude generated code or third-party sources with the --index-exclude flag
- Integrate into CI by running periphery scan and checking the exit code for regressions
Key Features
- Compiler-accurate analysis via the Swift index store rather than text matching
- Supports Xcode projects, Swift Package Manager, and Bazel build systems
- Incremental scanning that reuses previous build artifacts for faster re-scans
- Configurable severity levels to distinguish warnings from hard errors in CI
- Xcode-compatible output format so results appear as warnings in the IDE
Comparison with Similar Tools
- SwiftLint — enforces style rules; Periphery finds dead code specifically
- Xcode's built-in warnings — catches some unused variables; Periphery goes deeper into types and protocols
- fus — simpler unused code finder; Periphery uses the compiler index for accuracy
- Sourcery — code generation tool; Periphery is the opposite, finding code to remove
- swift-dependencies — tracks module-level dependencies; Periphery works at the symbol level
FAQ
Q: Does it support Swift Package Manager projects? A: Yes. Periphery builds SPM projects with swift build and analyzes the resulting index store.
Q: Can it produce false positives? A: Rarely. It may flag declarations used only via runtime features like @IBAction or Codable synthesis. Use the comment annotation // periphery:ignore to suppress those.
Q: How long does a scan take? A: The initial scan requires a full build, which depends on project size. Subsequent scans with incremental builds typically complete in seconds.
Q: Does it work with mixed Objective-C and Swift projects? A: Yes. It scans Objective-C bridging headers and detects unused @objc-exposed Swift declarations, though pure Objective-C analysis is limited.