Find and eliminate dead code in Android projects
A fast Rust CLI to detect and safely remove dead code in Android projects (Kotlin & Java). Inspired by Periphery for Swift.
brew install KevinDoremy/tap/searchdeadcode # macOS / Linux
cargo install searchdeadcode # via Cargo- Fast. Parse 1 000 files in under 1 second; 10 000 files in under 5 seconds.
- Android-aware. Activities, Fragments, Compose, AndroidManifest, layout XMLs, DI annotations all auto-retained as entry points.
- Hybrid analysis. Combine static analysis with JaCoCo / Kover / LCOV coverage and R8
usage.txtfor confirmed findings. - Safe delete. Interactive, batch, and dry-run modes, with restore script generation.
- Pairs well with kotlin-jump for editor-side navigation.
| Feature | SearchDeadCode | Android Lint | R8 / ProGuard | Detekt | IntelliJ |
|---|---|---|---|---|---|
| Speed | <1s/1k files | Slow | Build-time | Medium | Medium |
| Kotlin-first | ✅ | Partial | ✅ | ✅ | ✅ |
| Java support | ✅ | ✅ | ✅ | ❌ | ✅ |
| Safe delete | ✅ Interactive | ❌ | ❌ | ❌ | IDE only |
| CI / CD ready | ✅ SARIF, JSON | ✅ XML | ❌ | ✅ SARIF | ❌ |
| Coverage integration | ✅ JaCoCo, Kover, LCOV | ❌ | ❌ | ❌ | ❌ |
| Cycle detection | ✅ Zombie code | ❌ | ❌ | ❌ | ❌ |
| Resource detection | ✅ | ✅ | ❌ | ❌ | ✅ |
| Standalone (no build) | ✅ | ❌ | ❌ | ❌ | ❌ |
| License | MIT | Apache | Proprietary | Apache | Proprietary |
When to reach for each: SearchDeadCode for fast CI feedback and project audits. Android Lint for broader Android-specific checks. R8 for production-build accuracy. Detekt for style and complexity. IntelliJ for interactive refactoring inside the IDE.
# Analyze your Android project
searchdeadcode ./my-android-app
# Preview what would be deleted (no changes)
searchdeadcode ./my-android-app --delete --dry-run
# High-confidence findings only
searchdeadcode ./my-android-app --min-confidence high$ searchdeadcode ./my-app --min-confidence high
SearchDeadCode v0.4.0
Found 247 files to analyze
Reachability: 1 847 reachable, 2 103 total
Found 12 dead code issues:
Confidence Legend:
● Confirmed (runtime) ◉ High ○ Medium ◌ Low
app/src/main/java/com/example/data/OldApiClient.kt
◉ 15:1 warning [DC001] class 'LegacyApiClient' is never used
app/src/main/java/com/example/utils/StringUtils.kt
◉ 42:5 warning [DC001] function 'formatLegacyDate' is never used
◉ 67:5 warning [DC001] function 'parseOldFormat' is never used
Summary: 12 issues in 4 files (3 classes, 5 functions, 4 properties)
Estimated removable lines: ~340
| Category | Detected |
|---|---|
| Core | Unused classes, interfaces, methods, functions, properties, fields, imports |
| Advanced | Unused parameters, enum cases, type aliases |
| Smart | Assign-only properties, dead branches, redundant public modifiers |
| Android | Activities, Fragments, XML layouts, AndroidManifest entries (auto-retained) |
| Resources | Unused strings, colors, dimens, styles, attrs |
Full reference and code examples for each detector: docs/detectors.md.
brew tap KevinDoremy/tap
brew install searchdeadcodecargo install searchdeadcodeDownload from GitHub Releases. Available for Linux x86_64/aarch64, macOS Intel/Apple Silicon, Windows x86_64.
macOS may quarantine the binary. Run
xattr -d com.apple.quarantine ~/Downloads/searchdeadcode-macos-*thenchmod +xit. More options indocs/troubleshooting.md.
git clone https://github.com/KevinDoremy/SearchDeadCode
cd SearchDeadCode
cargo install --path .# Basic analysis
searchdeadcode ./app
# JSON output for programmatic use
searchdeadcode ./app --format json --output report.json
# SARIF for GitHub Code Scanning
searchdeadcode ./app --format sarif --output report.sarif
# Hybrid analysis with coverage + R8 usage
searchdeadcode ./app \
--coverage build/reports/jacoco/test/jacocoTestReport.xml \
--proguard-usage app/build/outputs/mapping/release/usage.txt \
--detect-cycles \
--min-confidence high
# Safe delete with dry-run
searchdeadcode ./app --delete --dry-runPower features: hybrid coverage analysis, R8 / ProGuard integration, zombie code detection, watch mode, baseline support, unused resources, unused params. See docs/cli-reference.md for the full CLI reference and docs/hybrid-analysis.md for coverage + R8 workflows.
# .github/workflows/dead-code.yml
name: Dead Code Detection
on: [push, pull_request]
jobs:
dead-code:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Detect Dead Code
uses: KevinDoremy/SearchDeadCode@v0
with:
path: '.'
format: 'sarif'
output: 'deadcode.sarif'
min-confidence: 'high'
fail-on-findings: 'true'
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: deadcode.sarifGitLab CI, Bitbucket, and pre-commit hook examples in docs/ci-integration.md.
SearchDeadCode looks for .deadcode.yml, .deadcode.toml, or a path passed via --config. Minimal example:
# .deadcode.yml
targets:
- "app/src/main/kotlin"
- "app/src/main/java"
exclude:
- "**/generated/**"
- "**/build/**"
- "**/test/**"
retain_patterns:
- "*Adapter"
- "*ViewHolder"
- "*Binding"
android:
parse_manifest: true
parse_layouts: true
auto_retain_components: trueFull schema (YAML + TOML) and Android-specific options: docs/configuration.md.
Being honest about limits helps you pick the right tool. Skip SearchDeadCode if:
- You need 100% accuracy. Static analysis cannot catch reflection or runtime-only references. Validate against R8
usage.txtinstead, or pass it via--proguard-usage. - Heavy reflection. Code accessed via
Class.forName()looks unused. Workaround: add reflection targets toretain_patterns. - Pure Java projects. SearchDeadCode is Kotlin-first. Java works but UCDetector or IntelliJ inspections may fit better.
- You want IDE integration. This is a CLI. Use IntelliJ / Android Studio's "Unused declaration" inspection, or run SearchDeadCode in
--watchmode alongside. - Dynamic targets (KMP JS). We analyze JVM bytecode patterns. JavaScript and other dynamic targets are out of scope.
But you'll likely want SearchDeadCode if you need: speed, CI integration, safe deletion with undo, hybrid coverage analysis, or no-build-required audits.
docs/detectors.md— 9 detection types with code examplesdocs/cli-reference.md— full CLI reference and command examplesdocs/configuration.md— YAML and TOML schemasdocs/hybrid-analysis.md— coverage, R8 / ProGuard, zombie codedocs/ci-integration.md— GitHub Actions, GitLab, pre-commit hooksdocs/troubleshooting.md— Gatekeeper, FAQ, known limitationsdocs/architecture.md— pipeline, tech stack, project structure, performance targetsdocs/research.md— dead code detection paradigms (Periphery, Meta SCARF, R8, tree shaking)docs/roadmap.md— 40 advanced patterns prioritized for future detectorsCHANGELOG.md— full version history
Contributions welcome. See AGENTS.md for the full contributor guide and CONTRIBUTING.md for the dev setup.
Good first issues: add new annotation patterns to entry_points.rs, improve XML parsing for additional attributes, write fixtures for edge cases.
- kotlin-jump — VS Code Kotlin/Java navigation, no JVM (4.6k+ installs).
- detekt-lsp — Live Detekt diagnostics for any LSP editor (pre-alpha).
- SearchDeadCode — this project.
Maintained alongside elumine-dev by Kevin Doremy.
MIT © Kevin Doremy Laferrière