Android project code style using Spotless and ktlint

Image for post
Image for post


When you write code, it’s always good to follow some common code style. But doing this manually, even using modern IDEs like Android Studio is painful — sooner or later you’ll forget about this.

This is especially important when you work in a team. If I (or you) press ⌘+⌥+L (autoformatting) pretty often, you can’t be sure that all your teammates do the same.

Of course, even with big problems in the code style, the code will compile successfully and would work absolutely equal with code with good code style. But it’s always better when your code is formatted following the common code style, diffs would be more readable and your colleagues will scold you less :)

How to solve the problem?

Image for post
Image for post

Spotless will help us! It allows us to format (and check rules) code in multiple languages, but we’re interested in Kotlin. Spotless uses ktlint to work with it.

ktlint’s standard rules are listed in its’ README, but let me duplicate some of them here:

  • 4 spaces for indentation
  • No semicolons (unless used to separate multiple statements on the same line)
  • No unused imports
  • No consecutive blank lines
  • No blank lines before }
  • etc

As you can see, it’s pretty useful. Let’s setup it!

Project integration

Image for post
Image for post

So, let’s assume that we have an Android project with Gradle, Kotlin, Java, and XML.

Spotless is provided as Gradle-plugin (not only Gradle, but we need just it).

First of all, add the following dependency to your project-level build.gradle:

It’ll look like this:

Then create spotless.gradle file, and add the following code to it:

The main configuration block is spotless, it contains rules for different file formats.

Let’s take a look at Java rules:

target specifies the mask of files for which the rules apply. For example, target '**/*.java' indicates that rules should be applied to all files with the .java extension in all directories.

Next, we list the rules for these files:

Rules names are self-describing, so I don’t think there is a need to describe any of them.

Next, we set the rules for the other languages — Kotlin, XML and other files, like Markdown, .gitignore, or .gradle.

Now we need to include spotless.gradle in our build — for example, in app/build.gradle:

Now app/build.gradle looks something like this:

Now you have just to synchronize your project with Gradle.


Gradle probably will raise this error during the synchronization:

If so, you have to remove the following block from your project-level build.gradle:

Setting up Android Studio

We have to change some settings in Android Studio to make it format code the right way.

First of all, install ktlint. On macOS the easiest way to do it is to use Homebrew:

Next, navigate to your project’s directory in the Terminal and execute this command:

The last thing to do is to disable wildcard imports in Android Studio. Go to the Preferences -> Editor -> Code Style -> Java and check the Use single class import checkbox, then increase Class count to use import with ‘*’ and Names count to use static import with ‘*’ values to something bigger, like 99.

Image for post
Image for post
Java settings

For Kotlin we need just to check the Use single name import radio buttons:

Image for post
Image for post
Kotlin settings

It’s done!

Using Spotless

Image for post
Image for post

Using Spotless is even easier than setting it up. We need just these two commands:

The first one is checking the code style and fails with an error if there are some problems.

The second one auto-formats the code. You can fix formatting issues in the whole project calling it. But only formatting — it can’t fix issues like wildcard imports, you have to fix them manually.

Now just execute these two commands before every Git push :)

Bonus: Travis CI integration

Image for post
Image for post

Every serious project uses some CI system, and it’s important to add code style checks in it.

For Travis CI it’s enough just to add ./gradlew spotlessCheck to the script block, and it will check your formatting on every build (and fail if there are some issues). Now your script block should look like this:

You can find the full config here.

Source code

You can find the full integration in the real project in this repository.

Have a nice day!

Written by

Senior Android Engineer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store