The Best Scala Code Formatters and Linting Tools

Have you ever faced the problem: your PR on github is not merged because you didn’t follow the project style-guide? Or your IDE is reformatting the whole file when you just want to modify one line? We had some of theses problems with our own code-base here at Wanari (most of the time when we need to patch a project that nobody has seen in an entire year). So we started to look for an automatic per-project code-styling tool (at first for our Scala code). The strange thing is that we didn’t find a good write-up about them. On the other hand, since we were already there, we started to read about the static analyzers and wanted to try out if we could profit from them. But we didn’t find a good write-up about these either. So this post will be a list of Scala code-styling and Scala static analyzing tools, barely comparing them, showing some pros and cons along with IDE and sbt integrations and tricks. (We will use the project names as the github page uses them.)

Scala code formatters

(Many thanks to @stsatlantis for creating this fabulous pic. – the Ed. :))

Code styling tools

These tools will count the spaces instead of you. Most of the IDEs have built-in file formatting (and most of the lazy programmers bind them to the file save action), but these are machine/IDE dependent and not project-dependent settings. You check out an open-source project and auto-format a file where you just inserted a safety if-else, and boom they reject your PR because you don’t follow the style-guide of the project. So you have to go through your code and fix the formatting errors as well… or you can use some tool which does it for you with project-dependent configurations. Fortunately, there are ( even compiler ) plugins which do it for you, and let you write the logic of the code as you type, and format it to something the community or coworkers want to/can read.

Scalariform

GitHub page: https://github.com/scala-ide/scalariform

Author and community: This tool is authored by the scala-ide, 400+ stars, 100+ forks, it’s the so-called official code formatting tool for Scala.

Overall thoughts: Awesome tool and widely used. It has a lot of configuration options and most of them are really useful, there are some fancy ones which are rather like rewriting arrow symbols. There is an IntelliJ plugin which can be useful but it doesn’t support per-project formatting, this is mainly because there is no option for external configuration.

Pros:

  • Keep your line formats which can be a con as well.
  • Lots of spacing properties
  • Compatible with the Scala Style Guide
  • Idempotent (it’s easy because it doesn’t check line length)
  • Per class/method format configuration (add/remove extra/unnecessary rules)
  • Fast
  • Moderate IDE integration
  • Sbt plugin

Cons:

  • Cannot format Dotty (yet)
  • IntelliJ plugin doesn’t support per project formatting

Usage tips:
After you get familiar with the concept it’s really easy to set up your own formatting. If you include the sbt plugin to your project the compile tasks will autoformat your code by default. If you don’t want this, you need to read the readme of the sbt project, it’s well documented and tells you how to switch auto-formatting off at compile. Worth to check how Akka uses it.

scalafmt

GitHub page: https://github.com/scalameta/scalafmt

Author and community: This tool is authored by the scalameta, 400+ stars, 80+ forks, it’s trying to point out some of the missing features of the scalariform.

Global thoughts: It’s a really well documented codeformatting tool. The site shows this as objectively as it can, most of the time honestly compared with scalariform (pros and cons for both tools). The config goes to a separate .conf file, and it handles line-sizes and empty-lines globally. It has project-dependent integration for most of the IDEs.

Pros:

  • handles most of the scalariform features
  • handles line-sizes and empty-lines
  • separate conf file → good IDE integration
  • can format Dotty

Cons:

  • can be slow (4-6x slower then scalariform but still manageable)
  • can be non idempotent (formating a file 2 times can be different but it happens rarely)

Usage tips:
If you want a good sbt integration (like formatting the source before compile), you will need to hack a bit. The sbt plugin is providing a command instead of a task so you can’t just depend on it at compile, but you can create a task and solve the problem.

You “need” to create a .scalafmt.conf file if you want the expected behavior. You can check how the alpakka configures and uses it.

Static analyzers

Static analyzers can check many aspects of your source code and can find class design problems, method design problems and also can have the ability to check code layout and formatting issues. A static code analyzer is a tool that flags suspicious language usage in the code. This can include behavior likely to lead to bugs, or non-idiomatic usage of a language, or just code that doesn’t conform to specified style guidelines.

Scalastyle

GitHub page: https://github.com/scalastyle/scalastyle

Author and community: This tool is authored by the scalastyle (they have a separate namespace), 400+ stars, 100+ forks, trying to be the java checkstyle for Scala.

Number of rules: Scalastyle implements 63 rules.

Rule-set: Some of the rules have something to do with formatting, like tab occurrence, spacing, etc. The rest of the rules would fit into the category of bad practices, but only a few checks can prevent bugs. It’s easy to enable/disable rules, because it generates the config for you and all you have to do is delete or set to ignore the rule.

Global thoughts: A good basic tool that helps your code be cleaner. The configuration is really easy, because it generates the config xml for you whenever you would like to dive into configuring it yourself.
You can find documentation on plugins to integrate with build tools (SBT, maven) and IDEs (Eclipse, IntelliJ), you can also read instructions on how to create your own Rule and how to import it to your project.
IntelliJ already integrated it and uses it as its default stylechecker.

Pros:

  • Well-documented
  • Easy to setup and configure
  • Plugins for build tools
  • Plugins for IDEs – actually no need for IntelliJ
  • CLI – Command Line Interface
  • Useful basic rules
  • Checks for line length and file length – a huge plus

Cons:

  • No checks for advanced features (Option.get, Traversable unsave methods)
  • Not so informative messages on the console

Usage tips:
It’s pretty easy to integrate to your compilation process. Just add

To be the part of your compilation project:

It’s a great tool along with another one from the list. We really like the integration with IntelliJ.

Scapegoat

GitHub page: https://github.com/sksamuel/scapegoat

Author and community: This tool is not under any organisation, but still has a pretty active community with 150+ stars, 25+ forks, trying to widen the Scala static analyzers palette.

Number of rules: 107

Rule-set: There are all types of checks in here (3 levels, you can easily modify the levels, switch off rules to project, or switch off rules by annotation)

Global thoughts: This project has a really good mindset, and it is widely configurable. There is a good number of checks, and project integration is not so hard. The whole thing would profit from better documentation and maybe a bit more flexibility. We will definitely try this on our new projects (or on the refactor cycles on some not so new projects).

Pros:

  • high number of checks
  • highly configurable
  • html / xml / findbugs / scalastyle reports for good compatibility
  • sbt plugin (can be used in compile with a small hack)

Cons:

  • lack of documentation
  • you need to do educated guesses sometimes
  • if you want a new check rule, you will have a bad time (because of the first point, and because you need to PR and wait or recompile the whole thing)

Usage tips:

In the plugin docs there are some “errors”. One of these is the version, and the other is the proper scalaOptions set. [If you left the ‘in Scapegoat’ out, and you don’t use the scapegoat as part of the compile (like the third line), some of your tasks will simply fail.]

After proper configuration, the sbt scapegoat task will work and also: if you have error level rules they can break the build.

WartRemover

GitHub page: https://github.com/wartremover/wartremover

Author and community: This tool has a separate space, 650+ stars, 50+ forks, trying to remove some nasty features from Scala and help you to write safer code.

Number of rules: There 32 built-in checks and there is a separate community project with a couple more useful checks.

Rule-set: Some of the checks are very reasonable because they try to avoid bad practices ,- e. g. usage of return keyword- but mostly contains rules to avoid known, frequently appearing bugs. If you don’t need wart detection in some part of your code, you can easily turn off linting for the given method/class by annotating it with @SuppressWarnings and giving it an Array of Warts you want to exclude.

Global thoughts: Most of the rules are worthy of at least playing around with.  Some of them, like the Any rule, have a problem with Actors; because of the implementation of the receive method, they require a PartialFunction[Any,Unit] – which fails.
You need to define the rules inside your sbt file, which can be strange and makes it harder to configure compared to other tools, but on the other side it guarantees type safety.

Pros:

  • Easy to write your own warts
  • Easy to install and setup
  • CLI tool
  • Manual Compiler plugin
  • Easy to calibrate
  • Well documented
  • Active community

Cons:

  • Not so easy to import your own warts

Usage tips:  Pretty straight-forward documentation and easy to set up. We wouldn’t recommend using Wart.Unsafe on the error level because there will be many false positive hits, one of them is mentioned above.

Linter

GitHub page: https://github.com/HairyFotr/linter

Author and community: This tool is not under any organisation, but still has a pretty active community with 200+ stars, 25+ forks, trying to point out ineffectivity (is that a word? :D) and possible bugs.

Number of rules: 123

Rule-set: there are all types of checks in here (switch on-off rules to project, or switch off rules with comments)

Global thoughts: If you just want an out of the box, fast and easy solution for trying out static analyzers on your code-base, this is the tool you’ve been searching for. But if you want a more permanent, more configurable thing, I think this isn’t really what you want. My biggest problem with this tool is that it can’t fail the build easily and it has only a compiler plugin. So running it separately is problematic too (maybe these can be achieved if you are more familiar with sbt but most of the other tools in this list could do these out of the box). It’s a good tool, but is not fit to our scope (but really ideal for small home-projects where the clean code is a nice to have feature and not a must have thing (wink)).

Pros:

  • flexible per line ignores
  • high number of checks

Cons:

  • sbt compiler plugin only, or manual setup
  • hacky if you want to fail your build if there are warnings
  • if you want a new check rule you will have a bad time (because the code of the project is not really developer friendly, and because you need to PR and wait, or recompile the whole thing)

Usage tips:
If you follow the install steps in the github page you will have a good code-smell warner with only 1 line of copy-paste (big grin)

If you want to break the compile on compiler warning you can do this according to this answer.

 

Abide

GitHub page: https://github.com/scala/scala-abide

Author and community: This tool is authored by Scala, 200+ stars, 25+ forks, trying to provide a lint-like rule creation framework.

Number of rules: core ~20, extra ~2, akka ~1

Rule-set: nonSafe/badPractice/possibleBug (at the moment you can’t turn them in/out easily)

Global thoughts: This is an updated, well documented, still underused tool. I personally think this tool should have a better spot in the Scala community. In its github page they say this is a “framework” and I think this is the biggest problem with it, because it has only a few rules and checks (but at least they wrote how you can forge some new down). I think this would be my personal favorite if the rule-set would be bigger, we get more Presenters (like the mentioned HTML5 output), and of course if it would get an actual release (smile)

Pros:

  • well documented
  • “easy” to extend with own rules
  • sbt AND compiler plugin, but can be used as a cli tool too

Cons:

  • not yet released
  • only a few rules
  • some nice to have features are only at the “further work” section

Usage tips:
I would not use it yet, but it has some really nice concepts, keep an eye on this!

Scala clippy

GitHub page: https://github.com/softwaremill/scala-clippy

Author and community: This tool is authored by a company from Poland, 200+ stars, 10+ forks, trying to help you understand the not so readable Scala warnings/errors.

Global thoughts: This is not a code-checker tool, but it’s kind of fit for this set anyway. So this will check your compiler errors and warnings, and try to hint with some common solves. You can add it to your projects as a compiler plugin, or use it globally on all of your sbt builds. If you write your own tool/framework, you could add some project specific errors to your future users too to help them, but the global database is easily extendable too.

Pros:

  • at compile not just compliments but advises too
  • the whole idea

Cons:

  • in some IDEs you will need to play a lot for a working solution
  • small data-set

General help for setup

sbt things

Most of the time the sbt integration is strange and problematic for users. (Especially if you’ve never used it before.) So this section will tell you some of the basics to help you.

If you get some addSbtPlugin, you need to insert that line to the project/plugins.sbt (create an empty file if it doesn’t exist). This type of integration will give you some Task or Command. You can use them like ‘sbt pluginname’ most of the time. If this is a command (IntelliJ will tell you if you write it in the build.sbt) you have a harder time; most of the time you can ctrl+click to it, and reverse engineer the main class and its default parameters and create a task from the command (I do this at the scalafmt section). If you have a task, you can run it before (or after) the compile. If you want to add some scalacOptions to it, you can do it by task, so you can more easily turn on/off the integrations. (These task creations or other option tunings go to the build.sbt .) You can write some custom tasks too, for example if you want to run more tasks to one keyword.


If you get some addCompilerPlugin, you need to insert it to the build.sbt, and this will run with every compile. This type of plugin is harder to configure. If you want to fail the build with this type of plugins you can try this.

git pre-commit hook

So we have a shiny project, we set up the code formatter, the code analyzers, we have tests, and we want to force the devs to use these standards (a.k.a. run the tools before commit, and fix the issues if there are any). There is a super method called pre-commit hook. If you set it properly, the developers will have a harder time if they want to dirty patch some code (smile) These hooks belong to the project/.git/hooks and our pre-commit hook will be the following:

  • we set the working directory

     
  • if we have non staged changes we stash them and after the build pop them again

     
  • we run the compile, the tests and give some human-readable output

     
  • we clean up the formatting modifications (we list the files already + we don’t want to collide with the pop at the end)  (Be careful this could do some unwanted side effects! On my git version sometimes it collides and messes up all of my staged and unstaged files. Our advice is to avoid committing with unstaged files, it is always safer if you stash manually before commit. Another approach is if you just test with your formatting tool.)

     

 

  • At the end we inform the user and return with the valid status code

     

All wrapped up together:

(This will work on Windows too \o/ ! This hook (mostly) came from this gist.)

The only problem with this code is that it’s not shared with all the repo cloners (it’s some sort of security thing to protect the users from unwanted code execution). If you want to force your team to use this hook, and if you want to version control it, the best way is to make a “hook” folder in the project, and give an easy method to “install” these hooks. This “easy” method most of the time is a script that creates symbolic links. (And there the fun things coming because of unix-like vs windows shells, and you still need to run it at least once per dev machine.)

Bash script:

Windows script:

 

Summary

Every tool comes with its advantages and disadvantages but you don’t have to be stuck with one tool only, combine them freely. We decided to take another way: we selected the required checks. In our case we decided to choose two linting tools Scapegoat along with WartRemover  the Scalafmt. We hope this article helped you to choose the right tool for your needs!

Let us know if you use any other tools worth mentioning. Any content on the page is open for improvement and open for discussion, so let us know if you have anything to agree/disagree on.

 

Barnabás Oláh

Barnabás Oláh

Full-stack Developer at Wanari Ltd.
Never underestimate the capabilities of a lazy person.

Gergő Törcsvári

Gergő Törcsvári

Software Developer at Wanari
I would love to change the world, but they won’t give me the source code (yet).