How does ktlint use .editorconfig, and what are some rules you can tune there (e.g. code style, line length, import ordering)?
answer
- .editorconfig is the single config surface
- ktlint_code_style: official / intellij_idea / android_studio
- ktlint_standard_<rule> = disabled to toggle a rule
- ktlint_experimental = enabled opts in
- @Suppress("ktlint:standard:rule-id") for local override
basics
~10 sktlint reads its limited settings from a .editorconfig file at the project root. There you set things like the code style flavor, max line length, indent size, and whether to allow certain rules.
solid answer
~30 sktlint deliberately exposes only a handful of knobs, all through standard **`.editorconfig`** files (it respects the `root = true` hierarchy). Common properties: `ktlint_code_style` (`ktlint_official`, `intellij_idea`, or `android_studio`), `max_line_length`, `indent_size`, `ij_kotlin_imports_layout`, and `ktlint_function_naming_ignore_when_annotated_with` (for @Composable). You can scope settings with section globs like `[*.{kt,kts}]`. Individual rules can be disabled via `ktlint_standard_<rule-id> = disabled` or whole rule sets via `ktlint_standard = disabled` / `ktlint_experimental = enabled`. Because config lives in `.editorconfig`, the same rules apply in the IDE, the CLI, and the Gradle plugin — one source of truth. You can also suppress per-line with `// ktlint-disable` (older) or the standard `@Suppress("ktlint:standard:rule-id")` annotation.
go deeper
Knows .editorconfig is where ktlint settings live and can set max_line_length.
Can pick a code style flavor, toggle individual rules, and enable the experimental set via property names.
Understands the .editorconfig resolution chain, scoping by glob, @Suppress overrides, and one-source-of-truth across IDE/CLI/Gradle.
Designs a shared .editorconfig strategy across multi-module/monorepo, balances strictness vs friction, and governs rule-set evolution.
## Why .editorconfig `.editorconfig` is a cross-editor, cross-tool config format. ktlint chose it so that **one file** drives the formatter, the IDE, and the CLI — there is intentionally no separate ktlint DSL. ktlint honors the `.editorconfig` resolution chain: it walks up directories until it finds `root = true`, merging the matching `[glob]` sections. ## Common properties ```editorconfig root = true [*.{kt,kts}] ktlint_code_style = ktlint_official # or intellij_idea, android_studio max_line_length = 120 indent_size = 4 ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^ insert_final_newline = true ``` - **`ktlint_code_style`** — selects the rule flavor. `ktlint_official` (the recommended default), `intellij_idea`, or `android_studio`. - **`max_line_length`** — drives the wrapping/line-length rule; `off` disables it. - **`ij_kotlin_imports_layout`** — controls import ordering/grouping (no wildcard imports by default in official style). ## Enabling / disabling rules and rule sets Each rule has an id like `standard:no-wildcard-imports`. You toggle them in `.editorconfig`: ```editorconfig [*.{kt,kts}] ktlint_standard_no-wildcard-imports = disabled # turn one rule off ktlint_experimental = enabled # opt into the experimental set ktlint_function_naming_ignore_when_annotated_with = Composable ``` - **Standard rule set** (`ktlint_standard`) — stable, on by default. - **Experimental rule set** (`ktlint_experimental`) — newer rules, off by default; opt in per-rule or globally. ## Per-code suppressions When a rule must be broken locally, use the `@Suppress` annotation with the `ktlint:` prefix: ```kotlin @Suppress("ktlint:standard:no-wildcard-imports") import kotlin.collections.* ``` The older inline `// ktlint-disable <rule>` / `// ktlint-enable <rule>` comment pair still works but is deprecated in favor of `@Suppress`. ## One source of truth Because everything lives in `.editorconfig`, the Gradle `ktlintCheck`/`ktlintFormat` tasks, the standalone CLI, and the IntelliJ ktlint plugin all behave identically — eliminating 'works in my IDE' drift.
- How do you make ktlint accept @Composable functions named in PascalCase without disabling function naming globally?Set ktlint_function_naming_ignore_when_annotated_with = Composable in .editorconfig, so the function-naming rule skips functions annotated with @Composable.
- Why does config in .editorconfig reduce 'works on my machine' problems?The IDE plugin, CLI, and Gradle plugin all read the same .editorconfig, so every tool applies identical rules and settings.
saying these in an interview costs you the question
- Claiming ktlint has its own JSON/YAML/DSL config file
- Not knowing how to disable a single rule
- Confusing standard vs experimental rule sets
- Thinking .editorconfig only affects whitespace and not rule toggles
- Disabling whole rule sets when one property would do