Skip to content

Consider adopting a Kotlin formatter (ktlint / Spotless) #105

@dalinaum

Description

@dalinaum

Context

The project currently has no automated Kotlin formatter. Developers rely on the Android Studio built-in IntelliJ formatter, and there is no CI gate for formatting. Occasional formatting drift shows up in PRs.

This issue captures the tradeoffs so the decision is recorded and doesn't need to be re-derived the next time it comes up.

Options

Tool Style basis Opinionation AS integration
ktlint JetBrains official Kotlin style Medium — tunable via .editorconfig .editorconfig shared, or IntelliJ plugin
ktfmt Google Java Format variant High — few options IntelliJ plugin
Spotless Wrapper — invokes ktlint or ktfmt internally Inherits chosen engine Via Gradle task

Benefits of adoption

  • Eliminates low-value review comments on whitespace, import order, trailing commas.
  • Removes formatting noise from PR diffs — reviewers see only logic changes.
  • CI gate means formatting discipline isn't a reviewer burden.

Costs and considerations

  1. One-time massive reformat commit. git blame history is disrupted across the commit. Mitigation: register the SHA in .git-blame-ignore-revs so blame skips it.
  2. AndroidX follows ktlint, but that isn't automatic evidence of a good fit here. Our current AS formatter habits may clash. Mitigation: introduce .editorconfig first and verify the diff is manageable before committing to a tool.
  3. ktlint versions add new rules routinely. A minor ktlint bump can turn CI red overnight. Mitigation: pin the version, update in dedicated PRs.
  4. Spotless is a wrapper, not a decision. Choosing Spotless leaves the ktlint-vs-ktfmt choice open.
  5. Compose DSL formatting varies by tool. Trailing lambdas, nested modifier chains, and @Composable fun declarations get reformatted differently across tools. A Compose-heavy file should be the pilot.

Incremental path (no tool installed yet)

A cheap first step that delivers ~80% of the value without installing anything:

# .editorconfig at project root
root = true

[*.{kt,kts}]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4
max_line_length = 120
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = true

Android Studio reads .editorconfig natively — no plugin needed. This alone removes most whitespace-related review noise. If more strictness is desired later, ktlint/Spotless can be layered on top without conflicting (.editorconfig becomes the shared source of truth).

Recommended sequence if fully adopted

  1. Add .editorconfig, tune so the diff from current AS formatting is minimal.
  2. Add Spotless Gradle plugin with ktlint engine (AndroidX precedent).
  3. Dry-run spotlessApply on 5–10 representative files, review the diff manually.
  4. Commit the full reformat; register the SHA in .git-blame-ignore-revs.
  5. Add ./gradlew spotlessCheck to CI.

Revisit triggers

Adopting these tools has real costs. It's worth waiting for at least one of:

  • Team size grows beyond 1–2 active contributors
  • Formatting comments appear in >50% of PRs
  • An external contributor opens a PR (where stylistic mismatch is most disruptive)

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions