Swift Deep Insight: Unused Code Detection
Detect unused (dead) code in Swift projects using the Swift compiler's index store.
Prerequisites
Xcode Projects
Build the project in Xcode first — the index store is created automatically at ~/Library/Developer/Xcode/DerivedData/<Project>/Index/DataStore.
SPM Projects
Build with xcodebuild -scheme <scheme> build or swift build.
Commands
Run from the project root or specify a path:
# Scan current directory
swift run swift-deep-insight --project-path .
# Verbose output
swift run swift-deep-insight --project-path . --verbose
# Xcode-clickable output (file:line:column:)
swift run swift-deep-insight --project-path . --xcode-format
# Include public declarations (normally excluded)
swift run swift-deep-insight --project-path . --include-public
Options
| Option | Description |
|--------|-------------|
| --project-path | Path to Swift project (default: current directory) |
| --verbose | Enable detailed logging |
| --xcode-format | Output in Xcode-compatible format (file:line:column:) |
| --include-public | Include public declarations in unused analysis |
| --exclude-tests | Exclude test targets from analysis |
| --build | Build the project before scanning (default: false) |
Gotchas
- No index store = limited results: Without the index store, analysis falls back to source-only parsing and misses cross-file references. Always build first.
- Runtime reflection is invisible: Code used via
responds(to:),perform(), or other runtime mechanisms will appear unused even though it's called. - External packages are not analyzed: Only your project's code is scanned, not dependencies.
- Public declarations are excluded by default: Public/API symbols are assumed to be used by consumers. Use
--include-publicto override. - Entry points are auto-detected:
main,@main,@NSApplicationMain, andAppDelegateare treated as roots — everything reachable from them is "used".
Workflow
- Build: Ensure the project is built so the index store is fresh
- Scan: Run the analyzer with appropriate flags
- Review: Examine unused declarations — verify each is truly dead code before removing
- Validate: After removal, rebuild and run tests to confirm nothing was incorrectly classified