Kotlin-NKP is a static analysis tool for Kotlin programs (nkp stands for aNalysis of Kotlin Programs).
nkp helps you understand and assess the architecture and structure of your Kotlin codebase by analyzing package dependencies, class hierarchies, and import relationships. It generates metrics and visual diagrams that aid in architectural decision-making, identifying coupling issues, and planning refactoring efforts.
- Parse your project - Convert your Kotlin source code into an analyzable JSON model
- Generate metrics - Calculate package coupling, class statistics, and file-level metrics
- Visualize dependencies - Create Mermaid diagrams showing class hierarchies, import flows, and package coupling
- Analyze architecture - Use the metrics to identify unstable packages, high coupling, and architectural issues
- Architectural Assessment: Understand package structure and dependencies in your codebase
- Refactoring Planning: Identify unstable packages and high coupling that need attention
- Documentation: Generate visual diagrams of your code structure
- Code Review: Get insights into package organization and dependencies
- Migration Planning: Understand dependencies before large-scale refactoring
| Capability | Supported | Not Supported |
|---|---|---|
| Architectural Analysis | ||
| Package dependency analysis | ✅ | |
| Package coupling metrics (Ca, Ce, I) | ✅ | |
| Import dependency tracking | ✅ | |
| Class hierarchy analysis | ✅ | |
| Code Quality Metrics | ||
| Class-level statistics | ✅ | |
| File-level statistics | ✅ | |
| Cyclomatic complexity | ❌ | |
| Lines of code metrics | ❌ | |
| Code duplication detection | ❌ | |
| Dependency Analysis | ||
| Package import relationships | ✅ | |
| Class inheritance trees | ✅ | |
| Circular dependency detection | ✅ | |
| Unused import detection | ❌ | |
| Dependency distance metrics | ❌ | |
| Visualization | ||
| Mermaid class diagrams | ✅ | |
| Mermaid import flow diagrams | ✅ | |
| Mermaid coupling diagrams | ✅ | |
| Temporal Analysis | ||
| Change frequency analysis | ❌ | |
| Historical metric trends | ❌ | |
| Code Smells | ||
| Large class detection | ❌ | |
| Long method detection | ❌ | |
| Deep inheritance detection | ❌ |
Summary: nkp excels at architectural and structural analysis (package coupling, dependencies, class hierarchies) but does not provide code quality metrics (complexity, size, code smells) or temporal analysis (change history, trends).
You can run the program with bin/nkp.sh or with just run.
$ bin/nkp.sh -h
Usage: nkp [<options>] <command> [<args>]...
Options:
-v, --version Show the version and exit
-h, --help Show this message and exit
Commands:
parse Parse a source directory and generate a model file.
circular-dependencies Detect circular dependencies between packages
class-statistics Class statistics
file-statistics File statistics and imports report
mermaid-class-diagram Mermaid class diagram
mermaid-coupling-diagram Generate a Mermaid coupling diagram from code analysis
mermaid-import-diagram Mermaid import diagram
package-coupling Generate package coupling metrics
package-statistics Package statistics
packages Packages report
search Search for a class by name- Java 17+ (for building dependencies)
- Gradle (included via wrapper)
- just (optional, for convenience commands)
- ktlint (optional, for code formatting)
This project uses custom libraries to parse Kotlin source code. You need to build these first:
Run the installation script:
$ bin/install-libs.shNote: The installation script requires Java 17. The project itself targets JVM 21.
- mermaid-cli - useful for converting Mermaid diagrams to SVG/HTML
The first step is to parse the files in a directory to a JSON file.
$ bin/nkp.sh parse /repositories/ray-tracer-challenge/src/main/kotlin generated/model.jsonFor projects with multiple source directories (e.g., Kotlin Multiplatform), use the --sources option:
$ bin/nkp.sh parse src/main/kotlin --sources=src/commonMain/kotlin,src/jvmMain/kotlin generated/model.jsonUse this JSON file in the analysis steps as input.
Generate a Mermaid class diagram:
$ bin/nkp.sh mermaid-class-diagram generated/model.json > generated/class-diagram.mermaidGenerate statistics:
$ bin/nkp.sh class-statistics generated/model.json > generated/class-statistics.json
$ bin/nkp.sh file-statistics generated/model.json > generated/file-statistics.json
$ bin/nkp.sh file-statistics --include-private-declarations generated/model.json > generated/file-statistics-full.json
$ bin/nkp.sh package-statistics generated/model.json > generated/package-statistics.jsonGenerate diagrams:
$ bin/nkp.sh mermaid-import-diagram generated/model.json > generated/import-diagram.mermaid
$ bin/nkp.sh mermaid-import-diagram --include-all-libraries generated/model.json > generated/import-diagram-all.mermaid
$ bin/nkp.sh mermaid-coupling-diagram generated/model.json > generated/coupling-diagram.mermaid
$ bin/nkp.sh mermaid-coupling-diagram --include-all-libraries generated/model.json > generated/coupling-diagram-all.mermaidSearch for classes:
$ bin/nkp.sh search generated/model.json MyClassDetect circular dependencies:
$ bin/nkp.sh circular-dependencies generated/model.json > generated/circular-dependencies.json
$ bin/nkp.sh circular-dependencies --include-all-libraries generated/model.json > generated/circular-dependencies-all.jsonList packages:
$ bin/nkp.sh packages generated/model.json > generated/packages.jsonNKP is also available as a Gradle plugin for easy integration into your build process.
Add the plugin to your project's build.gradle.kts:
plugins {
id("net.dinkla.nkp") version "0.1"
}Note: The plugin requires the kotlin-grammar-tools library to be available in mavenLocal. Run bin/install-libs.sh first.
nkp {
// Source directories to analyze (defaults to src/main/kotlin)
sourceDirs.set(listOf(
file("src/main/kotlin"),
file("src/commonMain/kotlin")
))
// Output directory (defaults to build/nkp)
outputDir.set(layout.buildDirectory.dir("nkp"))
// Configure which reports to generate
reports {
classStatistics.set(true) // JSON class statistics
fileStatistics.set(true) // JSON file statistics
packageStatistics.set(true) // JSON package statistics
packageCoupling.set(true) // JSON coupling metrics
packages.set(false) // JSON packages report
mermaidClassDiagram.set(true) // Mermaid class diagram
mermaidImportDiagram.set(true) // Mermaid import diagram
mermaidCouplingDiagram.set(true) // Mermaid coupling diagram
includeAllLibraries.set(false) // Include external libraries in diagrams
includePrivateDeclarations.set(false) // Include private declarations
}
}| Task | Description |
|---|---|
nkp |
Run all NKP tasks (parse + analyze) |
nkpParse |
Parse Kotlin source files and generate model.json |
nkpAnalyze |
Run all configured analyses on the parsed model |
# Run all NKP analysis
./gradlew nkp
# Output is in build/nkp/
ls build/nkp/
# model.json class-statistics.json file-statistics.json ...$ ./gradlew check$ ./gradlew jacocoTestReport
$ open build/reports/jacoco/test/html/index.htmlThe project uses refreshVersions for dependency management.
To update dependency versions:
$ ./gradlew refreshVersions- Root
directoryplus afilesarray. Each entry captures a Kotlin file withfilePath,packageName,imports, anddeclarations(classes, functions, properties, type aliases). Declarations are serialized using the domain model (ClassSignature,FunctionSignature, etc.), matching the Kotlin AST produced by the parser.
- JSON array where each item summarizes a class-like declaration. Fields:
className,packageName, optionalclassModifier/inheritanceModifier/visibilityModifier, and ametricsobject with counts (parameters, superTypes, declarations, classes, functions, properties, aliases, superClasses, subClasses).
- JSON array of per-file summaries. Each item includes
filePath,imports(list of fully qualified names),declarationswith names and optionalvisibilityModifier,metrics(counts of imports, declarations, classes, functions, properties, aliases), andcoupling(afferentCoupling, efferentCoupling, instability).
- JSON array of package-level rollups. Each entry has
packageName,importedElements(distinct imports),importStatistics(total/distinct and per-relationship counts), anddeclarationStatistics(files, functions, properties, classes, typeAliases).
- JSON array listing each package with its
imports(packages it depends on) and acouplingobject (afferentCoupling, efferentCoupling, instability). Useful for spotting stable/unstable packages.
- JSON array of packages. Each package contains
packageNameand itsfiles; every file repeatsfilePath,packageName,imports, and fully expandeddeclarations(including nested declarations), mirroring the source structure.
- JSON object that captures a search result:
classes(matches),superClasses, andsubClasses, each expressed as serialized class signatures with parameters, supertypes, and modifiers.
- JSON object containing circular dependency analysis results:
cycles: Array of detected cycles, each containing a list ofpackagesinvolved in the cyclehasCycles: Boolean indicating if any cycles were foundtotalCycles: Number of cycles detectedpackagesInCycles: Set of all packages that participate in at least one cycle
- Uses Tarjan's algorithm to find strongly connected components (SCCs) in the package dependency graph
- Mermaid definition for the class diagram of the analyzed project. Shows classes, properties, and relationships; ready for
mermaid-clior any Mermaid renderer.
- Mermaid graph describing import relationships between packages in the project, excluding external libraries.
- Same structure as the import diagram but includes external/library packages to show full dependency edges.
- Mermaid graph showing package-level coupling within the project, annotated with instability ranges.
- Coupling diagram that also includes external/library packages, useful for seeing outbound dependencies beyond the codebase.
(c) 2023 - 2025 Jörn Dinkla https://www.dinkla.net


