Kotlin Formatter (ktfmt)

Paste Kotlin code, a Gradle Kotlin DSL script or an Android ViewModel and get ktfmt output in a moment. The formatter is WebAssembly running in your browser tab, not a remote service.

Input

Settings

History

Load from URL

About ktfmt

This tool uses ktfmt (WASM), the Kotlin formatter created at Meta and built on the Kotlin compiler’s PSI parser plus google-java-format’s layout engine. Unlike ktlint, which reports style violations, ktfmt simply reprints the whole file, so the result does not depend on how the input was laid out. Paste a one-line mess or a nearly tidy file and you get the same answer.

ktfmt also cleans up a few things beyond whitespace. It removes unnecessary semicolons, sorts imports lexicographically, drops imports that are clearly unused, and reflows KDoc comments to the line width. Expressions, names and string templates are never altered.

Both .kt sources and .kts scripts parse, so a build.gradle.kts with plugins { } and dependencies { } blocks is fair game.

Because ktfmt ignores your original line breaks, it is especially good at untangling code that was minified, generated or pasted from a chat window where the newlines were lost. Lambdas, when branches, extension functions and data classes all come back in their idiomatic shapes, and string templates such as "total=$total" are never touched.

The Style option

Style selects one of ktfmt’s three presets:

  • ktfmt (Meta) — the default and the style ktfmt is known for.
  • Google — the variant used by Google’s Android and Kotlin projects.
  • Kotlin coding conventions — the kotlinlang preset, which follows the official JetBrains guide most closely and is the usual choice for teams that previously used IntelliJ’s built-in formatter.

The presets differ in details such as where chained calls and trailing lambdas break. Indentation always follows the toolbar here: block indentation uses the indent you pick, and continuation lines (wrapped arguments, chained calls) get twice that amount. The line-width control maps to ktfmt’s maximum width, which is 100 when ktfmt runs on its own; the toolbar opens at 80.

Keyboard: Ctrl/Cmd+Enter formats, Ctrl/Cmd+Shift+C copies, Ctrl/Cmd+K opens the palette. Minify (Ctrl/Cmd+Shift+M) applies to data formats only, not Kotlin.

Gotchas

ktfmt needs input that parses. A missing parenthesis or an unterminated string stops it with a ParseError that includes the line and column, and nothing is reformatted until it is fixed.

Code that relies on a precise manual layout, such as a matrix of numbers or an aligned DSL, will be reflowed. ktfmt has no “ignore” comment, so keep such blocks in a separate file if their shape matters.

Removing unused imports is based on names that appear in the file. In a snippet that uses an extension function or operator imported at the top, ktfmt can occasionally consider the import unused; check imports after formatting partial files. When you only need data classes rather than formatting, the JSON to Kotlin converter generates them from a sample payload.

Examples

Sealed interface and when, Google style

The semicolons between nested classes disappear, a blank line separates members, and each when branch gets a line.

Input
sealed interface Result<out T>{data class Ok<T>(val value:T):Result<T>;data class Err(val message:String):Result<Nothing>}
fun <T> Result<T>.getOrElse(default:T):T=when(this){is Result.Ok->value;is Result.Err->default}
Output
sealed interface Result<out T> {
  data class Ok<T>(val value: T) : Result<T>

  data class Err(val message: String) : Result<Nothing>
}

fun <T> Result<T>.getOrElse(default: T): T =
    when (this) {
      is Result.Ok -> value
      is Result.Err -> default
    }
Open this example in the tool

Coroutines chain, Kotlin coding conventions

The trailing lambda stays on the signature line while the call chain wraps with continuation indentation.

Input
suspend fun loadAll(ids:List<String>):List<User> = coroutineScope{ids.map{id->async{api.fetchUser(id)}}.awaitAll().filter{it.active}.sortedBy{it.name}}
Output
suspend fun loadAll(ids: List<String>): List<User> = coroutineScope {
  ids.map { id -> async { api.fetchUser(id) } }
      .awaitAll()
      .filter { it.active }
      .sortedBy { it.name }
}
Open this example in the tool

Data class and service, default style

ktfmt (Meta) style adds spacing around colons and operators and puts every member of the class on its own line.

Input
data class Item(val sku:String,val qty:Int,val price:Double)
class Cart{private val items=mutableListOf<Item>()
fun add(item:Item){items+=item}
fun total():Double=items.filter{it.qty>0}.sumOf{it.qty*it.price}}
Output
data class Item(val sku: String, val qty: Int, val price: Double)

class Cart {
  private val items = mutableListOf<Item>()

  fun add(item: Item) {
    items += item
  }

  fun total(): Double = items.filter { it.qty > 0 }.sumOf { it.qty * it.price }
}
Open this example in the tool

Common errors and how to fix them

ErrorCauseFix
com.facebook.ktfmt.format.ParseError: 1:21: error: Expecting an expressionAn assignment, argument or return has nothing after it, often because the paste was cut short.Complete the expression at the reported line:column, or remove the dangling =.
com.facebook.ktfmt.format.ParseError: 1:17: error: Expecting ')'A parameter list or call was opened and not closed.Add the missing ) before the next { or the end of the line.
com.facebook.ktfmt.format.ParseError: 1:28: error: Expecting '"'A string literal is not closed on the same line.Add the closing quote, or use a raw string (triple quotes) for multi-line text.

Frequently asked questions

What is the difference between ktfmt and ktlint?

ktfmt rewrites the whole file into one canonical layout. ktlint checks rules and can auto-correct some of them, but leaves most of your own line breaks alone.

Which style matches Android Studio?

Kotlin coding conventions (kotlinlang) is the closest to the official style that Android Studio applies by default. Set the indent to 4 as well.

Can I format build.gradle.kts files?

Yes. Kotlin scripts parse like regular Kotlin, so Gradle Kotlin DSL files format normally.

Why did an import disappear?

ktfmt removes imports it believes are unused. In a partial snippet that may include imports the rest of the project needs, so review them before committing.

Related tools