Languages / Kotlin

Kotlin code analysis: dead code, architecture and Android

To analyse a Kotlin or Android codebase, detekt and Android Lint cover style, complexity and unused resources. repowise adds a repository-wide graph shared with Java: Android manifest components and Spring beans are entry points, Kotlin Multiplatform actual declarations pair with their expect, and unused code is ranked by confidence from git history.

Last reviewed: November 2026

Full tier

What repowise detects in Kotlin

Checked against the engine source. Every row runs locally with zero LLM calls.

repowise capabilities for Kotlin
Files parsed.kt, .kts
Import resolutionFull. Shared JVM index with Java and Scala, Gradle source-set graph
Call graphResolved calls, inheritance and interface implementation
Dead codeUnreachable files, unused exports; Kotlin Multiplatform expect/actual rules
Health markersComplexity and class metrics
Performance markersSpring Data or Exposed queries in forEach, runBlocking or Thread.sleep inside suspend fun, Ktor client calls in loops, regex in loops
Coverage reportsJaCoCo XML (Kover can write it), Cobertura
Frameworks recognisedAndroid manifest components, Spring (Kotlin @Bean signatures), Jakarta, Quarkus, Micronaut; data class and Lombok synthetic members

Specific to this language

How Kotlin code is read

Kotlin Multiplatform without false positives

An actual declaration whose expect is in the repository is not reported, and neither is a file whose top-level actual pairs that way. An expect is reported only after a re-check for a real use: with one, it falls below the review floor; without one, it stays in the review tier.

Android components are entry points

Activities, services, receivers and providers named in AndroidManifest.xml are roots, so a screen the system launches is not reported as unreachable. Gradle source sets such as src/test/kotlin and src/*Test are recognised as test code.

Coroutine performance markers

runBlocking or Thread.sleep inside a suspend fun is flagged as blocking in async code. A repository query inside ids.forEach { } counts as a loop, which catches the common N+1 written with collection lambdas.

Honest comparison

Native Kotlin tools, and when they are enough

Native Kotlin analysis tools
ToolWhat it covers
detektStatic analysis for Kotlin: complexity rules, UnusedPrivateMember and related rules, code smells.
Android LintUnused resources, Android API misuse and performance issues in Android projects.
IntelliJ / Android Studio inspectionsUnused declarations within a project, in the IDE.
KoverKotlin coverage; can write JaCoCo-compatible XML for repowise.

Where repowise adds value

  • Architecture of a large app: Leiden communities, C4 views and a dependency map across Kotlin and Java modules, with no build.
  • Multiplatform-aware dead code across commonMain and platform source sets.
  • Hotspots, ownership and co-change from git history on the same graph.
  • Agent context: Claude Code, Cursor or Codex can ask how a feature flows through the modules over MCP.

How to run it

Analyse a Kotlin repository

From the repository root. Agents get the same results through the get_dead_code, get_health and get_context MCP tools.

uv tool install repowise        # or: pipx install repowise
repowise init --yes --no-prose     # index the repo, no API key
repowise dead-code --min-confidence 0.7 --safe-only
repowise health --refactoring-targets
./gradlew koverXmlReport
repowise coverage add build/reports/kover/report.xml
repowise serve                     # graph, health and dead code in a local dashboard

Questions

What people ask before they try it.

How do I analyse the architecture of a Kotlin Android app?

Run repowise init on the project and open repowise serve. You get the module dependency map, Leiden communities, C4 container and component views and an exportable Structurizr model, built from the Kotlin and Java sources and the manifest, with hotspots and owners overlaid from git history.

Does it handle Kotlin Multiplatform expect and actual?

Yes. Actual declarations that pair with an expect in the repository are not reported. An expect is reported only when no real use of its name is found.

Is it a detekt replacement?

No. detekt is a Kotlin linter with many style and complexity rules that runs in the build. repowise works at repository level: unreachable files, cross-module dead code, health scores that combine complexity with churn and coverage, and history.

Does repowise send my Kotlin code to an LLM?

No. Parsing, the call graph, dead code, health scores, performance markers and git history all run locally with zero LLM calls. repowise init --yes --no-prose needs no API key, and the analysis itself makes no network calls. Written documentation prose is the one opt-in step that uses a model, and it can run on a local Ollama model.

Index a Kotlin repository.

Public repositories are free on repowise.dev. The CLI is open source and runs on your machine with no API key.