Code quality tools in Kotlin projects
Code quality tools help you enforce coding standards, detect bugs early, measure test coverage, and maintain code quality across your Kotlin projects. This guide shows how to integrate popular tools like ktlint, detekt, SonarQube, SonarCloud, and Kover into your backend project for Maven or Gradle.
Code formatting with ktlint
ktlint is a Kotlin linter and formatter that enforces the official Kotlin coding conventions with no extra configuration.
ktlint checks rules such as indentation, spacing around operators, import ordering, and trailing commas. If a violation is found, the build fails with a message indicating the file and line number. Besides reporting violations, ktlint can also automatically fix straightforward issues.
To integrate ktlint into your project:
Add the plugin to your build file:
<!-- pom.xml --> <plugin> <groupId>com.github.gantsign.maven</groupId> <artifactId>ktlint-maven-plugin</artifactId> <version>3.7.1</version> <executions> <execution> <id>check</id> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin>// build.gradle.kts plugins { id("org.jlleitschuh.gradle.ktlint") version "12.3.0" }Run the linter to check your code style:
mvn ktlint:check./gradlew ktlintCheck(Optional) You can also add an
.editorconfigfile to the root of your project to customize rules. For example, to allow wildcard imports and disable trailing comma enforcement:[*.{kt,kts}] ij_kotlin_imports_layout = * ktlint_standard_trailing-comma-on-call-site = disabled ktlint_standard_trailing-comma-on-declaration-site = disabledBy default, ktlint follows the official Kotlin coding conventions. If you prefer the Android Kotlin style guide, which differs noticeably from the Kotlin conventions, set the code style to
android_studioin your.editorconfigfile:[*.{kt,kts}] ktlint_code_style = android_studioTo automatically fix formatting issues, run:
mvn ktlint:format./gradlew ktlintFormat
For more information on available features and rules, see the ktlint documentation.
Code analysis with detekt
detekt is a static code analysis tool for Kotlin that detects code smells, complexity issues, and potential bugs.
To integrate detekt into your project:
Add the plugin to your build file:
<!-- pom.xml --> <plugin> <groupId>com.github.ozsie</groupId> <artifactId>detekt-maven-plugin</artifactId> <version>1.23.8</version> <executions> <execution> <phase>verify</phase> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin>// build.gradle.kts plugins { id("io.gitlab.arturbosch.detekt") version "1.23.8" }Generate a default
detekt.ymlconfiguration file:mvn detekt:generate-config./gradlew detektGenerateConfigOpen the
detekt.ymlfile and customize the rules in the generated file, for example:complexity: LongMethod: threshold: 50 style: MagicNumber: active: falseReference the configuration file in your build file so that detekt can apply the new rules:
<!-- pom.xml --> <plugin> <groupId>com.github.ozsie</groupId> <artifactId>detekt-maven-plugin</artifactId> <version>1.23.8</version> <configuration> <config>detekt.yml</config> <report> <report>txt:reports/detekt.txt</report> <report>xml:reports/detekt.xml</report> </report> </configuration> <executions> <execution> <phase>verify</phase> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin>// build.gradle.kts detekt { toolVersion = "1.23.8" config.setFrom(file("config/detekt/detekt.yml")) buildUponDefaultConfig = true }Run the analysis:
mvn detekt:check./gradlew detekt
detekt produces a report listing all rule violations with their severity, file location, and a description of the issue. By default, Gradle outputs reports to build/reports/detekt, while Maven outputs to the reports/detekt directory in the project root.
For more information, see the detekt documentation for Gradle and Maven.
Code quality with SonarSource
SonarQube and SonarCloud from SonarSource provide deep static analysis for Kotlin projects, including bug detection, vulnerability scanning, and code coverage tracking through a web dashboard.
To analyze your project with SonarQube:
Add the plugin to your build file:
<!-- pom.xml --> <plugin> <groupId>org.sonarsource.scanner.maven</groupId> <artifactId>sonar-maven-plugin</artifactId> <version>5.7.0.6970</version> </plugin>// build.gradle.kts plugins { id("org.sonarqube") version "6.2.0.5505" } sonar { properties { property("sonar.projectKey", "my-project") property("sonar.host.url", "http://localhost:9000") } }(Optional) Configure analysis properties. For example, to make the build wait for the quality gate result and fail if the gate is not passed, add the
sonar.qualitygate.waitproperty:mvn verify sonar:sonar \ -Dsonar.qualitygate.wait=true \ -Dsonar.projectKey=my-project \ -Dsonar.host.url=http://localhost:9000 \ -Dsonar.token=YOUR_TOKEN// build.gradle.kts sonar { properties { property("sonar.qualitygate.wait", "true") } }Run the analysis against your SonarQube server:
mvn verify sonar:sonar \ -Dsonar.projectKey=my-project \ -Dsonar.host.url=http://localhost:9000 \ -Dsonar.token=YOUR_TOKENFor SonarCloud, replace the host URL with
https://sonarcloud.ioand provide your organization key:mvn verify sonar:sonar \ -Dsonar.projectKey=my-project \ -Dsonar.organization=my-org \ -Dsonar.host.url=https://sonarcloud.io \ -Dsonar.token=YOUR_TOKENTo run the analysis, use the
sonartask and provide your authentication token:./gradlew sonar \ -Dsonar.token=YOUR_TOKENBy default, the analysis is run against a local SonarQube server. To use SonarCloud, update the
sonar {}block in yourbuild.gradle.ktsto usehttps://sonarcloud.ioand add your organization key:sonar { properties { property("sonar.projectKey", "example-project") property("sonar.organization", "example-org") property("sonar.host.url", "https://sonarcloud.io") } }Open the SonarQube or SonarCloud dashboard to review the results. The dashboard shows issues grouped by type (bug, vulnerability, code smell) and severity.
For more information, see the SonarSource documentation.
Code coverage with Kover
Kover is the official JetBrains code coverage tool for Kotlin. It measures which lines and branches of your code are covered by tests and generates human-readable reports.
Unlike JaCoCo, Kover correctly interprets Kotlin-specific constructs such as inline functions and data classes, so it reports accurate coverage numbers without false negatives caused by compiler-generated bytecode.
To integrate Kover into your project:
Add the plugin to your build file:
<!-- pom.xml --> <plugin> <groupId>org.jetbrains.kotlinx</groupId> <artifactId>kover-maven-plugin</artifactId> <version>0.9.8</version> <executions> <execution> <id>instr</id> <goals> <goal>instrumentation</goal> </goals> </execution> <execution> <id>kover-verify</id> <goals> <goal>verify</goal> </goals> </execution> <execution> <id>kover-report-xml</id> <goals> <goal>report-xml</goal> </goals> </execution> <execution> <id>kover-report-html</id> <goals> <goal>report-html</goal> </goals> </execution> </executions> </plugin>// build.gradle.kts plugins { id("org.jetbrains.kotlinx.kover") version "0.9.8" }Run your tests to collect coverage data and generate the report:
mvn verify./gradlew koverVerify koverHtmlReportOpen the HTML report generated in the
target/site/kover/html/directory (build/reports/kover/html/for Gradle) to review line-by-line coverage.(Optional) To enforce a minimum coverage threshold that fails the build if the conditions are not met, you can add a coverage verification configuration to your build file. For example:
<!-- pom.xml --> <configuration> <!-- Create new coverage verification rule --> <rules> <rule> <bounds> <bound> <minValue>50</minValue> <coverageUnits>LINE</coverageUnits> <aggregationForGroup>COVERED_PERCENTAGE</aggregationForGroup> </bound> </bounds> </rule> </rules> </configuration>// build.gradle.kts // Add a `kover` configuration block import kotlinx.kover.gradle.plugin.dsl.* kover { reports { total { log { aggregationForGroup = AggregationType.COVERED_PERCENTAGE coverageUnits = CoverageUnit.LINE } verify { rule { minBound(50) } } } } }
For more information on configuring verification rules, see the Kover documentation for Maven and Gradle.
Other tools
Besides ktlint, detekt, SonarQube, SonarCloud, and Kover, try out other tools to improve Kotlin code quality:
Tool | Description |
|---|---|
Semantic code analysis engine by GitHub. Supports Kotlin and integrates with GitHub Actions to find security vulnerabilities automatically. | |
Fast, lightweight static analysis tool that supports custom rules. Can be used to enforce patterns or detect anti-patterns in Kotlin code. | |
Source code analyzer that supports Kotlin (via its CPD copy-paste detector) and detects common programming flaws and duplicate code. |