LemonAppDev Konsist for Kotlin Architecture Rules
Konsist is a powerful static code analyzer tailored for Kotlin, focused on ensuring codebase consistency and adherence to coding conventions.
At a glance
- What is it?
- Konsist is a Kotlin static code analyzer that expresses codebase consistency checks as JUnit or Kotest tests. It suits teams that want package, naming, inheritance, annotation, and architecture constraints checked through ordinary test infrastructure.
- Who is it for?
- Adopt Konsist for Kotlin repositories whose conventions are specific enough to express as structural tests, especially projects with explicit architecture layers. Do not choose it as a general replacement for compilation, runtime, security, or code-style checks.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Kotlin, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Konsist Checks in Kotlin Projects
Konsist addresses structural consistency in Kotlin codebases. Its target is not formatting or runtime behaviour. The project is designed for teams that have conventions such as package placement, class suffixes, inheritance relationships, annotation use, and layer dependencies, but want those conventions checked automatically instead of relying on review comments.
The relevant users are Kotlin developers, Android teams, Spring projects, and maintainers of layered applications. The README gives examples for a general Kotlin rule, an Android `ViewModel` rule, a Spring `Repository` annotation rule, and a clean-architecture dependency rule. These examples show that Konsist treats source declarations as queryable objects rather than scanning raw text for isolated patterns.
Konsist also fits organizations already using JUnit or Kotest. A rule is written as a unit test, so the same execution environment used for normal tests can report a consistency violation. That design makes the analyzer familiar to teams that already treat structural policies as executable specifications. It does not automatically prove that every convention is correct, however. The value depends on the rules that a team writes and on whether those rules match the actual architecture.
Konsist Scope, Queries, and Assertion Flow
The examples describe a scope, a declaration query, and an assertion. The entry points are `Konsist.scopeFromProject()` and `Konsist.scopeFromProduction()`. The repository documentation says the API reflects Kotlin structure, including classes, functions, properties, interfaces, and annotations. The README does not specify the implementation details of parsing or indexing, so the safe description is that Konsist exposes Kotlin declarations through a queryable API.
For example, the general Kotlin check starts from the project scope, selects classes whose names end in `UseCase`, and asserts that each selected class resides in a matching package. The Android check selects classes with `ViewModel` among their parents and then requires the `ViewModel` name suffix. The Spring check begins with interfaces carrying `Repository` and requires the same suffix on those interfaces.
The architecture example uses `scopeFromProduction()` and `assertArchitecture`. It declares `Domain`, `Presentation`, and `Data` layers by package patterns, then states that Presentation and Data may depend on Domain while Domain depends on nothing. This is a different level of operation from selecting named declarations. The rule is about the relationship between packages, which makes it useful for detecting an invalid dependency direction before a manual architecture review.
Adding Konsist to Gradle and Maven Tests
The README provides dependency declarations for Gradle Kotlin, Gradle Groovy, and Maven. These entries add Konsist as a test dependency, which matches its unit-test model. The README lists `1.0.0-alpha.1` in all three examples, while the repository release history includes `v0.18.1` as a recent release. The examples therefore should not be treated as evidence that `1.0.0-alpha.1` is the current release without checking the project release documentation.
For a Gradle Kotlin project, add the dependency to the test configuration:
testImplementation("com.lemonappdev:konsist:1.0.0-alpha.1")For a Gradle Groovy project, use the equivalent declaration:
testImplementation "com.lemonappdev:konsist:1.0.0-alpha.1"For Maven, add the dependency with test scope:
<dependency>
<groupId>com.lemonappdev</groupId>
<artifactId>konsist</artifactId>
<version>1.0.0-alpha.1</version>
<scope>test</scope>
</dependency>After adding the dependency, the README directs new users to the Konsist documentation and the starter projects. It does not provide a separate plugin installation step or a documented CLI command, so neither should be assumed.
A First Konsist Naming and Package Test
The shortest first use is a unit test that defines one convention and checks the declarations selected by that convention. The following example is copied from the README. It selects classes ending in `UseCase` and requires them to reside in a `usecase` package:
@Test
fun `classes with 'UseCase' suffix should reside in 'usecase' package`() {
Konsist.scopeFromProject()
.classes()
.withNameEndingWith("UseCase")
.assertTrue { it.resideInPackage("..usecase..") }
}Place the test in the test source set used by the project, then run the normal JUnit or Kotest task. The README does not state the exact Gradle or Maven task name, so it does not support inventing a command such as `gradlew test` or `mvn test` here. The expected result is that the selected classes satisfy the package condition. If the project contains a class with the required suffix outside that package, the assertion is intended to fail as a test.
This pattern is easy to read because the test name describes the policy, the query narrows the relevant declarations, and the assertion expresses the rule. It also exposes a limitation: the rule only examines classes selected by `withNameEndingWith("UseCase")`. A different spelling or a class that should be a use case but lacks the suffix would not be caught by this test.
Android, Spring, and Clean Architecture Checks
Konsist's examples extend beyond package naming. The Android example uses `ViewModel::class` to identify classes with a particular parent and then checks their names. This is a structural inheritance rule, not a runtime Android instrumentation test. It can report a naming mismatch in a source tree, but it does not establish that a screen behaves correctly or that a `ViewModel` is configured correctly on a device.
@Test
fun `classes extending 'ViewModel' should have 'ViewModel' suffix`() {
Konsist.scopeFromProject()
.classes()
.withAllParentsOf(ViewModel::class)
.assertTrue { it.name.endsWith("ViewModel") }
}The Spring example applies the same idea to annotations. It selects interfaces annotated with `Repository` and requires a matching name suffix. The relevant source of truth for the annotation is the imported `Repository` symbol in the test, so the rule is tied to the project's actual type references.
@Test
fun `interfaces with 'Repository' annotation should have 'Repository' suffix`() {
Konsist
.scopeFromProject()
.interfaces()
.withAllAnnotationsOf(Repository::class)
.assertTrue { it.hasNameEndingWith("Repository") }
}The clean-architecture example instead defines layers by package patterns and checks allowed dependencies. This makes Konsist a candidate for dependency-direction rules in modular codebases. Its limits are equally concrete. The README does not document excluded files, generated sources, conditional compilation, or support for every Kotlin language feature, so those areas need verification in the project documentation before adoption.
Limitations Compared with Other Checks
Konsist is not a general-purpose Kotlin compiler, runtime test framework, or security scanner. Its rules operate on declarations and relationships. A passing Konsist suite cannot replace compilation, behavioral tests, dependency vulnerability scanning, or tests that verify application output. The README does not claim that Konsist performs those tasks.
A real alternative is to encode architecture rules in a conventional linter or in handwritten JUnit tests that inspect a codebase through a separate parsing approach. The difference is in the domain API. Konsist exposes Kotlin-oriented selectors such as `classes()`, `interfaces()`, `withAllParentsOf`, `withAllAnnotationsOf`, and `assertArchitecture`, so teams do not need to write every structural query as low-level text processing. The trade-off is that this convenience is tied to Konsist's API and its documented source scopes.
Another practical limitation is rule coverage. Konsist can only report what a test asks it to report. Naming, inheritance, and package rules are visible in the README, but it does not claim universal enforcement of conventional Kotlin style. Generated sources, unusual package layouts, and rules requiring semantic interpretation may need a separate tool or custom tests. The project's test-based delivery also means rule failures appear as test failures, which may require an agreed process for deciding whether a violation blocks a build.
Maintenance, Releases, and Apache-2.0 Implications
The repository is not archived. Its last push was on 2026-10-15, so the repository metadata indicates recent activity. The release history includes `v0.18.1` on 2026-10-10 and `v0.18.0` on 2026-10-09, with `v0.17.3` dated 2024-12-08. This supports recent release activity, but it does not by itself guarantee API stability or a fixed maintenance schedule.
The README's dependency examples use `1.0.0-alpha.1`, which is an alpha version and should be treated as an upgrade consideration. The project documentation and release notes do not establish a migration guide, compatibility matrix, rollback procedure, or policy for breaking API changes. Before adopting it as a build requirement, check the documentation and release notes corresponding to the selected version rather than assuming that the version naming in the README has converged.
Konsist is distributed under the Apache License, Version 2.0. The README points to `LICENSE` for details. That identifies the license, but it is not legal advice and does not answer organization-specific compliance questions. Teams should review the license file and dependency terms for their distribution model.
Editorial conclusion
Adopt Konsist for Kotlin repositories whose conventions are specific enough to express as structural tests, especially projects with explicit architecture layers. Do not choose it as a general replacement for compilation, runtime, security, or code-style checks. Verify dependency version stability, source-scope behavior, and rule coverage before making it a required check, because the README documents `1.0.0-alpha.1` while recent releases include `v0.18.1`.
Frequently asked questions
How do I install Konsist in a Kotlin project?
Add `com.lemonappdev:konsist:1.0.0-alpha.1` to the test dependency configuration. The README shows equivalent declarations for Gradle Kotlin, Gradle Groovy, and Maven.
How does Konsist check Kotlin architecture?
Konsist queries declarations through scopes such as `scopeFromProject()` and `scopeFromProduction()`. Its README demonstrates naming, package, inheritance, annotation, and layer-dependency assertions.
Does Konsist replace JUnit or Kotest?
No. The README describes Konsist guards as unit tests written with JUnit or Kotest. Konsist supplies the Kotlin structure queries and assertions, while the project supplies the test framework and test execution.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/lemonappdev-konsist)Was this useful?