Scalafmt - code formatter for Scala


Join the chat at

Any style guide written in English is either so brief that it’s ambiguous, or so long that no one reads it.
-- Bob Nystrom, "Hardest Program I've Ever Written", Dart, Google.

Scalafmt turns the mess on the left into the (hopefully) readable, idiomatic and consistently formatted Scala code on the right.

object FormatMe { List(number) match
{ case head :: Nil
if head % 2 == 0 => "number is even"
  case head :: Nil =>
  "number is not even"
  case Nil =>
  "List is empty" }
  arg5, "arg6")
  , arg7 + arg8),, 2,
  3, 4, 5, 6)) }
object FormatMe {
  List(number) match {
    case head :: Nil if head % 2 == 0 =>
      "number is even"
    case head :: Nil =>
      "number is not even"
    case Nil =>
      "List is empty"
    arg2(arg3(arg4, arg5, "arg6"),
         arg7 + arg8),, 2, 3, 4, 5, 6))

The goal of scalafmt is to produce good enough formatted code so that you can focus on programming instead of manipulating syntax trivia. Scalafmt can be used in several environments such as the command line, text editors and build tools.

It is not a goal to format every single Scala source file under the sun. In particular, scalafmt cannot format deeply nested computer generated code.

Scalafmt is maintained by @olafurpg in his free time. Bug reports, feature requests, questions and PRs are welcome. Complaints and unfriendly attitude is not welcome.

Curious to learn more about scalafmt? Check out this talk:



The recommended way to install the scalafmt command line tool is with Coursier.


NOTE To install Coursier see here

Create a standalone executable in /usr/local/bin/scalafmt with (sudo if necessary):

coursier bootstrap com.geirsson:scalafmt-cli_2.12:1.4.0 \
  -r bintray:scalameta/maven \
  -o /usr/local/bin/scalafmt --standalone --main org.scalafmt.cli.Cli
scalafmt --version # should be 1.4.0

Alternatively you can create a slim 15 KiB bootstrap script with:

coursier bootstrap com.geirsson:scalafmt-cli_2.12:1.4.0 \
  -r bintray:scalameta/maven \
  -o scalafmt --main org.scalafmt.cli.Cli
./scalafmt --version # should be 1.4.0
It is recommended to put this bootstrap script in your code repository to make sure everyone on your team, as well as CI, uses the same scalafmt version. To configure which files to format, see project.

To customize the JVM options, use the Coursier option --java-opt, more info with

coursier bootstrap --help | grep -A 1 "\-\-java-opt"


Our CI publishes a pre-release version of scalafmt to Bintray on every merge into master. To use a pre-release, replace 1.4.0 with the version here:

If you use coursier to install a pre-release, be sure to include the flag -r bintray:scalameta/maven so that the artifact can be resolved.

If you use sbt to install a pre-release, be sure to add the following setting

resolvers += Resolver.bintray("scalameta", "maven")


Nailgun is recommended if you want to integrate scalafmt with a text editor like vim/Emacs/Atom/Sublime/VS Code.

Nailgun keeps scalafmt running on a local server to avoid the JVM startup penalty and also so scalafmt can benefit from JIT. This makes scalafmt up to 10x faster when formatting a single file from the CLI. The downside to Nailgun is that the setup is complicated and the long-running server needs to be restarted once in awhile.


You can install scalafmt via Homebrew using a custom formula
brew install --HEAD olafurpg/scalafmt/scalafmt
scalafmt --version // should be 1.4.0

// to upgrade between releases
brew upgrade scalafmt


NOTE. This help page is generated from the master branch and may include flags that have not been published yet.
build commit: 433a73b3a5
build time: Thu Apr 19 09:42:31 UTC 2018
scalafmt 1.4.0-67-433a73b3
Usage: scalafmt [options] [<file>...]

  -h, --help               prints this usage text
  -v, --version            print version 
  <file>...                file or directory, in which case all *.scala files are formatted.
  --stdout                 write formatted files to stdout
  --git <value>            if true, ignore files in .gitignore (default false)
  --exclude <value>        file or directory, in which case all *.scala files are formatted.
  -c, --config <value>     a file path to .scalafmt.conf.
  --config-str <value>     configuration defined as a string
  --stdin                  read from stdin and print to stdout
  --no-stderr              don't use strerr for messages, output to stdout
  --assume-filename <value>
                           when using --stdin, use --assume-filename to hint to scalafmt that the input is an .sbt file.
  --test                   test for mis-formatted code, exits with status 1 on failure.
  --migrate2hocon <value>  migrate .scalafmt CLI style configuration to hocon style configuration in .scalafmt.conf
  --diff                   If set, only format edited files in git diff against master.
  --diff-branch <value>    If set, only format edited files in git diff against provided branch.
  --build-info             prints build information
  --quiet                  don't print out stuff to console.
  --debug                  print out diagnostics to console.
  --non-interactive        disable fancy progress bar, useful in ci or sbt plugin.
scalafmt # Format all files in the current project, configuration is determined in this order:
         # 1. .scalafmt.conf file in current directory
         # 2. .scalafmt.conf inside root directory of current git repo
         # 3. no configuration, default style
scalafmt --test # throw exception on mis-formatted files, won't write to files.
scalafmt --diff # Format all files that were edited in git diff against master branch.
scalafmt --diff-branch 2.x # same as --diff, except against branch 2.x
scalafmt --stdin # read from stdin and print to stdout
scalafmt --stdin --assume-filename foo.sbt < foo.sbt # required when using --stdin to format .sbt files.
scalafmt Code1.scala A.scala       # write formatted contents to file.
scalafmt --stdout Code.scala       # print formatted contents to stdout.
scalafmt --exclude target          # format all files in directory excluding target
scalafmt --config .scalafmt.conf   # read custom style from file
scalafmt --config-str "style=IntelliJ" # define custom style as a flag, must be quoted.
Please file bugs to


Here is the plugin. You can install it directly from within IntelliJ,

The default shortcut is Ctrl + Shift + L. Undo works, but not redo.

The plugin determines which style to use in this order:

  1. .scalafmt.conf in the project's root directory, if it exists
  2. $HOME/.scalafmt.conf, if it exists
  3. Otherwise, uses default style.
For details on how .scalafmt.conf should look like, see Configuration. The scalafmt IntelliJ plugin has a "Format on save" setting.

NOTE. You may need to enable balloons to get error message: Settings > Appearance & Behavior > Notifications > Scalafmt > Popup "Balloon". You need to first check "Display Balloon Notifications".


You can choose between


// In project/plugins.sbt. Note, does not support sbt 0.13, only sbt 1.0.
addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "1.4.0")
The plugin provides several tasks and settings.
object autoImport {
  val scalafmt = taskKey[Unit]("Format Scala sources with scalafmt.")
  val scalafmtCheck =
      "Fails if a Scala source is mis-formatted. Does not write to files.")
  val scalafmtOnCompile =
      "Format Scala source files on compile, off by default. " +
        "BEWARE. This task is not incremental, every file in the " +
        "project is re-formatted on every compile. " +
  val scalafmtConfig = taskKey[Option[File]](
    "Optional location of .scalafmt.conf file. " +
      "If None the default config is used.")
  val scalafmtSbt = taskKey[Unit](
    "Format *.sbt and project/*.scala files for this sbt build.")
  val scalafmtSbtCheck =
      "Fails if a *.sbt or project/*.scala source is mis-formatted. " +
        "Does not write to files.")
  val scalafmtOnly = inputKey[Unit]("Format a single given file.")
The sbt plugin is enabled by default for the Test and Compile configurations. To enable the plugin for integration tests
and then use it:scalafmt to format.

Pro tip. To share configuration across projects, you can define a setting in build.sbt to generate .scalafmt.conf programmatically on sbt load.

// define setting key to write configuration to .scalafmt.conf
SettingKey[Unit]("scalafmtGenerateConfig") :=
  IO.write( // writes to file once when build is loaded
    """style = IntelliJ
      |# Your configuration here


lucidsoftware/neo-sbt-scalafmt is an sbt plugin that


It is possible to use scalafmt in gradle with the following externally maintained plugins:


It is possible to use scalafmt in Maven with the following externally maintained plugin:


NOTE. You pay the JVM startup penalty on every format unless you're using Nailgun.

Standalone library

Add to your dependencies
libraryDependencies += "com.geirsson" %% "scalafmt-core" % "1.4.0"
libraryDependencies += "com.geirsson" %% "scalafmt-cli" % "1.4.0"
// Scala.js
libraryDependencies += "com.geirsson" %%% "scalafmt-core" % "1.4.0"

Use the API like this

scala> org.scalafmt.Scalafmt.format("""
      object FormatMe { List(Split(Space, 0).withPolicy(SingleLineBlock(close)), Split(Newline, 1).withPolicy{ case Decision(t@FormatToken(_, `close`, _), s) => Decision(t, List(Split(Newline, 0)))}.withIndent(2, close, Right)) }
res0: java.lang.String = 
"object FormatMe {
    Split(Space, 0).withPolicy(SingleLineBlock(close)),
    Split(Newline, 1)
      .withPolicy {
        case Decision(t @ FormatToken(_, `close`, _), s) =>
          Decision(t, List(Split(Newline, 0)))
      .withIndent(2, close, Right)

Help wanted!


Configuration for scalafmt is defined in a plain text file .scalafmt.conf using HOCON syntax. To reuse your configuration with IntelliJ, .scalafmt.conf must be placed in the root directory of your project.

Here is an example .scalafmt.conf.

align = true    # For pretty alignment.
maxColumn = 100 # For my wide 30" display.

A note of warning. I personally use the default style, which means that the default style is by far the most tested and supported style. Most of the configuration flags are quite innocent, while some of them work very differently (esp. Scala.js). It is very difficult to guarantee that all configurations options play nicely together so I recommend you try not to go too crazy on this part.

The following sections describe the most common configuration options.

NOTE. If you are using scalafmt as a Standalone library, you can pass in a ScalafmtConfig instance, which is set to ScalafmtStyle.default by default.


Option 1: default
// Column 40                           |
// non bin packed parent constructors
object DefaultStyle
    extends Parent
    with SecondParent
    with ThirdParent {
  // non bin packed arguments
    argument2(argument3, argument4))
  // Vertical alignment only for case arrows
  x match {
    case 1  => 1
    case 11 => 1
Option 2: IntelliJ
// Column 40                           |
// non bin packed parent constructors
object IntelliJStyle
    extends Parent
    with SecondParent
    with ThirdParent {

  function(argument1, argument2)

  // continuationIndent = 2  # for call + defn site
  // align.openParenCallSite = false
  // danglingParentheses = true

  // openParenCallSite = true
  def foobar(argument1: Type1,
             argument2: Type2): Int =
    argument1 + argument2

NOTE. There is a Scala.js style that is super experimental and does not work for complicated code.


Default: 80


Default: 2


  argument1 // indented by 2


Default: 4

Same as continuationIndent.callSite except for definition site. Example:

def function(
    argument1: Type1): ReturnType // Indented by 4


Default: some Align has several nested fields, which you can customize. However, it comes with four possible defaults: none, some, more, & most.


x match { // true for case arrows
  case 2  => 22
  case 22 => 222

def foo(a: Int, // true for defn site open paren
        b: String): Int
foo(a: Int, // true for call site open paren
    b: String): Int

val x = 2 // false for assignment
val xx = 22

case object B extends A // false for `extends`
case object BB extends A


x match { // false for case arrows
  case 2 => 22 // also comments!
  case 22 => 222 // don't align me!

def foo(
    a: Int, // false for defn site
    b: String): Int
  a: Int, // false for call site
  b: String): Int
Pro tip: Enable this setting to minimize git diffs/conflicts from renamings and other refactorings.


val x  = 2 // true for assignment
val xx = 22

case object B  extends A // false for `extends`
case object BB extends A

q  -> 22 // true for various infix operators
qq -> 3  // and also comments!

for {
  x  <- List(1) // true for alignment enumerator
  yy <- List(2)
} yield x ** xx

x match { // true for multiple tokens across multiple lines
  case 1  => 1  -> 2  // first
  case 11 => 11 -> 22 // second

  // A blank line separates alignment blocks.
  case `ignoreMe` => 111 -> 222

// Align assignments of similar type.
def name   = column[String]("name")
def status = column[Int]("status")
val x      = 1
val xx     = 22

// Align sbt module IDs.
libraryDependencies ++= Seq(
  "org.scala-lang" % "scala-compiler" % scalaVersion.value,
  "com.lihaoyi"    %% "sourcecode"    % "0.1.1"


for {
  // align <- with =
  x  <- List()
  yy = 2
  // aligns body by arrow
  zzz <- new Integer {
          def value = 3
} yield x
// Note. Only for the truest vertical aligners. This is a new option,
// feel free to open PR enabling more crazy vertical alignment here.
// Expect changes.


Default: [caseArrow]

An align token is a pair of code, which is the string literal of an operator of token, and owner, which is the kind of the closest tree node that owns that token. If no owner is provided, then all tree kinds will be matched.

// =======================================================
// scalafmt: {align.tokens = [{code = "=>", owner = "Case"}]}
// =======================================================
x match {
  case 1  => 1 -> 2
  case 11 => 11 -> 22
// =======================================================
// scalafmt: {align.tokens = ["%", "%%"]}
// =======================================================
val x = List(
  "org.scala-lang" % "scala-compiler" % scalaVersion.value,
  "com.lihaoyi"    %% "sourcecode"    % "0.1.1"
To find the owner part for a custom tree, depend on Scalameta and use scala.meta.Tree.productPrefix from the the (for example, Ammonite) repl
@ import $ivy.`org.scalameta:scalameta_2.12:1.7.0`, scala.meta._
@ val termMatch = q"x match { case 2 => foo(bar) }"
termMatch: Term.Match = x match {
  case 2 =>
@ termMatch.structure
res0: String = """
Term.Match(Term.Name("x"), Seq(Case(Lit.Int(2), None, Term.Apply(Term.Name("foo"), Seq(Term.Name("bar"))))))
@ termMatch.productPrefix
res1: String = "Term.Match"
To learn more about Scalameta, see this tutorial.


Default: false
// align.arrowEnumeratorGenerator = false
for {
  x <- new Integer {
    def value = 2
} yield x
// align.arrowEnumeratorGenerator = true
for {
  x <- new Integer {
        def value = 2
} yield x


Default: true
// Column limit |
// align.openParenCallSite = true
foo(arg1, arg2)

function(arg1, // align by (

// align.openParenCallSite = false
foo(arg1, arg2)
  arg1, // no align by (


Default: true
// align.openParenDefnSite = true
// Column limit                          |
class IntString(int: Int, string: String)

class IntStringLong(int: Int,
                    string: String,
                    long: Long)

// align.openParenDefnSite = false
// Column limit                          |
class IntString(int: Int, string: String)
class IntStringLong(
  int: Int,
  string: String,
  long: Long

// format: off

Disable formatting for specific regions of code by wrapping them in // format: OFF blocks:
object PrettyMatrix {
  // format: off
  val identity = Array(1, 0, 0,
                       0, 1, 0,
                       0, 0, 1)
  // format: on
To disable formatting for a whole file, put the comment at the top of the file.


Default: false

If true, the margin character | is aligned with the opening triple quote """ in interpolated and raw string literals.

// 40 columns                          |
object StripMargin {
  val example1 =
       |  * one
       |  * two
       |  * $three

  // pipe character after opening """
  val example2 =
        |  * one
        |  * two
        |  * $three
NOTE. May cause non-idempotent formatting in rare cases, see #192.


Default: ScalaDoc
// docstrings = ScalaDoc
/** Align by second asterisk.

// docstrings = JavaDoc
/** Align by first asterisk.


Default: false
// newlines.alwaysBeforeTopLevelStatements = false
import org.scalafmt
package P {
  object O {
    val x1 = 1
    val x2 = 2
    def A = "A"
    def B = "B"

// newlines.alwaysBeforeTopLevelStatements = true
import org.scalafmt

package P {

  object O {
    val x1 = 1
    val x2 = 2

    def A = "A"

    def B = "B"


Default: true
// Column limit                                                     |
// newlines.sometimesBeforeColonInMethodReturnType = true
implicit def validatedInstances[E](implicit E: Semigroup[E])
  : Traverse[Validated[E, ?]] with ApplicativeError[Validated[E, ?], E] = 2

// newlines.sometimesBeforeColonInMethodReturnType = false
implicit def validatedInstances[E](implicit E: Semigroup[E]): Traverse[
    Validated[E, ?]] with ApplicativeError[Validated[E, ?], E] = 2


Default: true
// spaces.afterKeywordBeforeParen = true
if (a) foo()
while (a) foo()
for (a <- as) foo()

// spaces.afterKeywordBeforeParen = false
if(a) foo()
while(a) foo()
for(a <- as) foo()


Default: false
// column limit                        |
// binPack.parentConstructors = false
object DefaultStyle
    extends Parent
    with SecondParent
    with ThirdParent {
  // body ...

// column limit                        |
// binPack.parentConstructors = true
object DefaultStyle
    extends Parent with SecondParent
    with ThirdParent {
  // body ...


Default: unix


Default: true
// includeCurlyBraceInSelectChains = true
  .map { x =>
    x + 2
  .filter(_ > 2)

// includeCurlyBraceInSelectChains = false
List(1).map { x =>
    x + 2
}.filter(_ > 2)
For more details, see this comment.


Default: true

If true, forces a select chain (pipeline) to break if there is a newline at the start of the chain.

// original
  .map(_ + 1)
  .filter(_ > 2)

// optIn.breakChainOnFirstMethodDot = true
  .map(_ + 1)
  .filter(_ > 2)

// optIn.breakChainOnFirstMethodDot = false + 1).filter(_ > 2)
// note. chain starts at .foo() in

See this comment for further motivation.


Default: true
// newlines.penalizeSingleSelectMultiArgList = true

// newlines.penalizeSingleSelectMultiArgList = false
  .elem(a, b, c)

See this comment for further motivation.


Default: false
// newlines.alwaysBeforeElseAfterCurlyIf = true
if(someCond) {
else {

// newlines.alwaysBeforeElseAfterCurlyIf = false
if(someCond) {
} else {


Default: true
// binPack.literalArgumentLists = true
val secret: List[Bit] = List(0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1,
  0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1,
  0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1)

// binPack.literalArgumentLists = false
val secret: List[Bit] = List(
  // really long list...


Default: 150

Set to -1 to disable. Increase number to require bigger argument bodies to trigger flag.

// Before: Argument body is too big
Account(userName = "user",
        fullName = "user@localhost",
        mailAddress = "",
        password = "",
        isAdmin = false,
        url = None,
        registeredDate = new Date(),
        updatedDate = new Date(),
        lastLoginDate = None,
        image = image,
        isGroupAccount = false,
        isRemoved = false)
// After: "config style"
  userName = "user",
  fullName = "user@localhost",
  mailAddress = "",
  password = "",
  isAdmin = false,
  url = None,
  registeredDate = new Date(),
  updatedDate = new Date(),
  lastLoginDate = None,
  image = image,
  isGroupAccount = false,
  isRemoved = false

Set runner.optimizer.forceConfigStyleMinArgCount = 1 to enable this rule for function calls with only 1 argument (default = 2).

By forcing config style, scalafmt is able to greatly optimize performance eliminating a large number of "search state exploded" errors. See these flame graphs.


Default: disabled

To enable a rewrite rule, add it to the config like this rewrite.rules = [SortImports].


a success b
a error (b, c)
a map { x =>
  x + 2
"o" % "a" % "v" c(D)
future recover {
  case e: Err => 0
} map (_.toString)
a.error(b, c) { x =>
  x + 2
("o" % "a" % "v").c(D)
  .recover {
    case e: Err => 0
For more examples, see this diff. Configuration contains include/exclude operator filters (those values are build in, and can't be configured outside)


import a.{
  }, h.{
    k, l
  import d.e.{f, g}
  import a.{
      foo => bar,
      zzzz => _,

import a.b
import a.c
import h.k
import h.l
import d.e.f
import d.e.g
import a.{foo => bar, zzzz => _, _}


Warning. This rewrite can cause Non-idempotent formatting, see #1055.
object RedundantBraces {
  def foo = {
    List(1, 2, 3).sum

  // stringInterpolation = true
  q"Hello ${name}"
object RedundantBraces {
  def foo =
    List(1, 2, 3).sum

  // stringInterpolation = true
  q"Hello $name"
Configuration options and default values:


Removes redundant parentheses in guard clauses.

object RedundantParenthesis {
  def c(b: List[Int]): List[Int] =
    for {
      a <- b
      if (a.nonEmpty)
    } yield a
object RedundantParenthesis {
  def c(b: List[Int]): List[Int] =
    for {
      a <- b
      if a.nonEmpty
    } yield a


The imports are sorted by the groups: symbols, lower-case, upper-case.

import foo.{Zilch, bar, Random, sand}
import foo.{bar, sand, Random, Zilch}


The imports are sorted by their Ascii codes

import foo.{~>, `symbol`, bar, Random}
import foo.{Random, `symbol`, bar, ~>}


Replaces parentheses into curly braces in for comprehensions that contain multiple enumerator generators.

object a {
  for(a <- as; b <- bs if b > 2)
    yield (a, b)
object a {
  for {
    a <- as
    b <- bs if b > 2
  } yield (a, b)


Configure which source files should be formatted in this project.

# Only format files tracked by git.
project.git = true
# manually exclude files to format.
project.excludeFilters = [
# manually include files to format.
project.includeFilters = [


Scalafmt has a ton of internal configuration options which may be removed without notice. However, just in case you want to try them out, here they are.
maxColumn = 80
onTestFailure = 
project.git = false
project.files = []
project.includeFilters = [".*\.scala$"
project.excludeFilters = []
align.openParenCallSite = true
align.openParenDefnSite = true
align.ifWhileOpenParen = true
align.treeCategory.Defn.Trait = class/object/trait
align.treeCategory.Enumerator.Val = for
align.treeCategory.Defn.Class = class/object/trait
align.treeCategory.Defn.Object = class/object/trait
align.treeCategory.Defn.Val = val/var/def
align.treeCategory.Defn.Def = val/var/def
align.treeCategory.Defn.Var = val/var/def
align.treeCategory.Enumerator.Generator = for
align.arrowEnumeratorGenerator = false
align.tokens = [code = "=>"
  owner = Case]
continuationIndent.callSite = 2
continuationIndent.defnSite = 4
continuationIndent.extendSite = 4
optIn.breaksInsideChains = false
optIn.blankLineBeforeDocstring = false
optIn.selfAnnotationNewline = true
optIn.annotationNewlines = true
optIn.breakChainOnFirstMethodDot = true
optIn.configStyleArguments = true
assumeStandardLibraryStripMargin = false
runner.optimizer.maxEscapes = 16
runner.optimizer.dequeueOnNewStatements = true
runner.optimizer.maxVisitsPerToken = 513
runner.optimizer.acceptOptimalAtHints = true
runner.optimizer.maxDepth = 100
runner.optimizer.forceConfigStyleMinArgCount = 2
runner.optimizer.disableOptimizationsInsideSensitiveAreas = true
runner.optimizer.forceConfigStyleOnOffset = 150
runner.optimizer.recurseOnBlocks = true
runner.optimizer.escapeInPathologicalCases = true
runner.optimizer.pruneSlowStates = true
runner.eventCallback = org.scalafmt.config.ScalafmtRunner$$$Lambda$4036/930761569@58b3ae73
runner.parser = scala.meta.internal.parsers.ScalametaParser$$anon$202@6dd620b2
runner.debug = false
runner.fatalWarnings = false
runner.maxStateVisits = 1000000
runner.ignoreWarnings = false
runner.dialect = Dialect(true, true, true, true, true, true, true, true, false, true, false, false, true, true, true, true, true, )
encoding = UTF-8
newlines.alwaysBeforeMultilineDef = true
newlines.afterImplicitKWInVerticalMultiline = false
newlines.alwaysBeforeElseAfterCurlyIf = false
newlines.neverInResultType = false
newlines.sometimesBeforeColonInMethodReturnType = true
newlines.alwaysBeforeTopLevelStatements = false
newlines.afterCurlyLambda = never
newlines.penalizeSingleSelectMultiArgList = true
newlines.neverBeforeJsNative = false
newlines.alwaysBeforeCurlyBraceLambdaParams = false
newlines.beforeImplicitKWInVerticalMultiline = false
version = 1.4.0
unindentTopLevelOperators = false
poorMansTrailingCommasInConfigStyle = false
indentOperator.include = ".*"
indentOperator.exclude = "^(&&|\|\|)$"
docstrings = ScalaDoc
lineEndings = unix
rewrite.rules = []
rewrite.redundantBraces.methodBodies = true
rewrite.redundantBraces.maxLines = 100
rewrite.redundantBraces.stringInterpolation = false
rewrite.redundantBraces.generalExpressions = true
rewrite.redundantBraces.includeUnitMethods = true
rewrite.neverInfix.includeFilters = ["[\w\d_]+"]
rewrite.neverInfix.excludeFilters = [until
danglingParentheses = false
includeCurlyBraceInSelectChains = true
binPack.literalsInclude = [".*"]
binPack.literalsExclude = [String
binPack.literalsMinArgCount = 5
binPack.unsafeCallSite = false
binPack.unsafeDefnSite = false
binPack.literalArgumentLists = true
binPack.parentConstructors = false
indentYieldKeyword = true
importSelectors = noBinPack
verticalMultilineAtDefinitionSite = false
spaces.neverAroundInfixTypes = []
spaces.beforeContextBoundColon = Never
spaces.inByNameTypes = true
spaces.afterTripleEquals = false
spaces.inImportCurlyBraces = false
spaces.inParentheses = false
spaces.afterKeywordBeforeParen = true


Scalafmt tries to automatically reformat as much as possible. However, sometimes you need to help scalafmt decide how to format your code.

Infix applications

Infix applications are methods calls that use the syntax like a + b instead of a.+(b). Scalafmt preserves your line breaks in infix applications, even if this means the maxColumn setting is not respected.
// column limit |
// if you have long infix appplications
a.b(c) && d.e(f, g, h)
// then scalafmt may format like this
a.b(c) && d.e(
  f, g, h)
// which is ugly. You can fix it by inserting
// a newline after && and it will look like this
a.b(c) &&
  d.e(f, g, h)

Config style

You can use "config style" to tell scalafmt to break a function application.
// Put newline after opening (
// and newline before closing )
// to force one argument on each line.

// OK: Config style
  longerArg1 = defaultValue1,
  longerArg2 = defaultValue2,
  longerArg3 = defaultValue3
// NOT Config style
function(longerArg1 = defaultValue1,
         longerArg2 = defaultValue2,
         longerArg3 = defaultValue3)


Related projects

Have a scalafmt related project? Please consider opening a pull request to list it here:


Are you using scalafmt? Please consider opening a pull request to list your organization here: Here are the download numbers from Maven Central. Here are the download numbers for the IntelliJ plugin.

FAQ / Troubleshooting

Why not Scalariform?

Scalariform does an excellent job of tidying up common formatting errors. However, Finally, scalafmt is my Master's thesis project. I thought it would be a fun challenge to write a code formatter :)

Why is scalafmt so slow?

My benchmarks show that scalafmt is for most common cases around 4-6x slower than scalariform (btw, scalariform is already impressively fast). This means that formatting your average 1.000 LOC file on modern hardware will take around 200ms, which should still feel close enough to instant.

The main feature that makes scalafmt slower than scalariform is the column-width limit. To figure the "best" way to break a long line, Scalafmt may try thousands of different formatting solutions.

I am sure that scalafmt could benefit greatly from micro optimizations. Any help here is appreciated.

Code formatters create unnecessary diffs!

That's not a question, but I agree that code formatters like scalafmt do sometimes increase the size of diffs in code reviews. I still believe it's worth it, considering

  1. Proper formatting helps you catch bugs!
  2. you can enable non-whitespace diffs during code review. For Github, add ?w=1 to the URL to ignore whitespace changes.
  3. git blame has a -w flag to ignore whitespace changes so you can still blame your colleagues for their crappy code.
  4. code is read waaay more often outside of code reviews, for example when you are actually coding.

Which configuration options minimize diffs/conflicts in version control?

  1. align=none If alignment is enabled a renaming of one entity can impact the indentation of other entities.
  2. danglingParenthesis=true Having the closing parenthesis on the same line as the last argument makes the diff line include the parenthesis and everything following it in case that argument is renamed. So, technically this does not reduce the number of diff lines, but the length of them.

Is the formatting output stable between releases?

No, the formatting rules will evolve even between PATCH releases. I recommend you inspect the diff for every scalafmt update.

Known issues

Developing code formatters is notoriously hard and scalafmt has been no exception. The following are the biggest known issues with scalafmt:

Deeply nested code

AKA. "Search state exploded"

0.5.0 made big improvements on this issue. In my test corpus, only 13 out of 27.000 source files trigger this error now.

Scalafmt cannot yet format all files with deeply nested functions calls. Deeply nested code is troublesome because the number of possible formatting options grows exponentially with each new layer of nesting. Instead of taking seconds or minutes to complete formatting, scalafmt chooses to bail early and leave the source file unformatted.

There are two workaround if you are affected by this issue:

Other cool code formatters like ClangFormat, dartfmt and rfmt use better techniques to solve this issue, which scalafmt can maybe learn from.


Scalafmt is non-idempotent for certain files. See #339. This means you should be careful about enforcing scalafmt in your CI build.

In my test corpus, as of v0.5.0, only 12 files out of 27.000 source files are affected by this issue. If sources are already formatted by scalafmt, no source file in the test corpus triggers non-idempotent formatting.

Pro tip. As awkward as I feel recommending this, you may want to run scalafmt twice on your codebase for the first time you reformat it.


Scalafmt is 6x slower than Scalariform. For 98% of source files this won't be a problem if you have a decently modern laptop. However, if you only work in files with 4.000 LOC it might be a problem. I'm quite sure that micro-optimizations can squeeze out at least ~2x performance improvements, maybe even more. Moreover, I think incremental formatting has the possibility to increase the performance by several orders of magnitude in interactive IDE environments where scalafmt is invoked on file save.




See merged PRs.



See merged PRs.



This release was identical to 1.0.0-RC4.



If no major issues are reported within one week of this release, then it will be promoted to v1.0. PS. If you are using sbt-scalafmt, please give neo-sbt-scalafmt a try!


See 1.0.0-RC3


See 1.0.0-RC3



NOTE. BROKEN RELEASE, use 1.0.0-RC1 instead. See #943 and




All of the fixes in this release are contributed by @pjrt, awesome work!


Fix concurrency bug in sbt-scalafmt.


Try to fix concurrency bug in sbt-scalafmt.


Try to fix concurrency bug in sbt-scalafmt.





Merged PRs:

3 million lines reformatted with 0.6.1 compared to 0.5.8: scala-repos#20



Merged PRs: Big thanks to @dwijnand and @tgodzik for contributing 5 and 2 pull requests each, respectively!


Merged PRs:





This release was made possible with contributions from 7 new contributors. Big thanks to @avdv, @pjrt, @MasseGuillaume, @mpociecha, @rbellamy, @ysusuk and @dguo-coursera! Also thanks to everyone who reported issues.












Big thanks to @cb372, @phalodi and @caoilte for contributing to this release!




Big thanks to everyone who contributed to this release: @mmatloka, @melrief, @stefanobaghino, @johnynek, @RatanRSur, @Gmadorell, @Synesso, @Lambdista and @easel




I'm really excited to announce this release with lots of new features and improvements.








Skipping, messed up Sonatype release.






NOTE. This release contains a bug, see #192. Please hold off from upgrading.

This release changes the formatting rules for many small cases. I recommend you reformat your whole project in one commit.










This page was last updated on Apr 19, 2018.

Fork me on GitHub