跪拜 Guibai
← All articles
Android · Android Jetpack · Kotlin

Your Design System Is a Contract: Enforce It with Konsist and Android Lint

By 稀有猿诉 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Without automated enforcement, design system violations accumulate silently across feature teams, forcing reviewers to repeat feedback and inflating UI maintenance costs. This layered approach converts written guidelines into CI-blocking rules, shifting the burden from human memory to the repository itself.

Summary

Design system drift happens because code review is not a reliable enforcement mechanism. The solution is to treat the design system as an engineering contract and automate its checks. For Jetpack Compose, that means layering three tools: Konsist for package and architecture boundaries, custom Android Lint detectors for forbidden source patterns, and Compose UI tests for runtime behavior.

The article walks through defining tokens for spacing, typography, colors, and shapes, then shows how Konsist tests can assert that feature packages never depend on design system internals. It then implements a concrete Lint detector that flags numeric literals in `Color()` constructors outside an approved allowlist, including issue registration, service loader setup, and unit tests that check both violations and legal exceptions.

The final part covers rollout strategy: start with a non-blocking audit, fix high-value violations, then make rules blocking in CI. The argument is that executable rules move design decisions into the repo itself, reducing the cost of maintaining hundreds of slightly different UI implementations.

Takeaways
— Konsist's assertArchitecture can express that feature layers must not depend on design system internal packages.
— Custom Android Lint detectors can flag numeric literals in Compose Color constructors outside an approved package allowlist.
— Lint rules need an IssueRegistry and a service loader registration under META-INF/services to be discovered.
— Detector tests should cover both violations and legal exceptions, otherwise a detector may silently break legitimate code.
— Rollout should be phased: audit existing violations, fix high-value cases, and only then set rules to blocking in CI.
— Design system tokens should centralize spacing, typography, shapes, and colors so feature code references semantic names rather than raw values.
— A narrow Lint rule around specific spacing APIs is more useful than flagging every dimension literal, since not all dp values represent spacing.
Conclusions

Code review is not a reliable enforcement mechanism: reviewers are time-constrained and the same feedback recurs across pull requests, so automation shifts responsibility from human judgment to the repository.

No single tool can enforce every design rule; methods must be matched to the kind of constraint, whether structural (Konsist), expression-level (Lint), or runtime (Compose UI tests).

The detector example shows that broad bans on dimension literals would mis-flag legitimate non-spacing uses, so rules need clearly scoped APIs and explicit contracts.

The emphasis on testing both violations and legal exceptions underscores that a detector without tests is just code that can silently fail to enforce anything.

The rollout approach of starting with an audit and then making rules blocking is a pragmatic way to avoid flooding CI with pre-existing violations.

Concepts & terms
Konsist
A Kotlin architecture testing library that lets developers write tests against package structure, dependency direction, and naming conventions, typically run as JUnit tests during build.
Android Lint custom detector
A Java/Kotlin class that implements Detector and scans source files for forbidden patterns, reported as issues with severity; custom issues are registered via an IssueRegistry and service loader.
Design tokens
Named values for spacing, typography, colors, and shapes that centralize design decisions; feature code references the token name instead of raw numbers, making changes manageable in one place.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗