JetpackCompose.app Home

Which lint rules does Jetpack Compose ship with?

Vinay Gaba on June 24, 2022
Article Hero Image

import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Paint
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
fun Modifier.coloredShadow(
color: Color,
alpha: Float = 0.2f,
borderRadius: Dp = 0.dp,
shadowRadius: Dp = 20.dp,
offsetY: Dp = 0.dp,
offsetX: Dp = 0.dp
) = composed {
val shadowColor = color.copy(alpha = alpha).toArgb()
val transparent = color.copy(alpha= 0f).toArgb()
this.drawBehind {
this.drawIntoCanvas {
val paint = Paint()
val frameworkPaint = paint.asFrameworkPaint()
frameworkPaint.color = transparent
frameworkPaint.setShadowLayer(
shadowRadius.toPx(),
offsetX.toPx(),
offsetY.toPx(),
shadowColor
)
it.drawRoundRect(
0f,
0f,
this.size.width,
this.size.height,
borderRadius.toPx(),
borderRadius.toPx(),
paint
)
}
}
}
view raw ColoredShadow.kt hosted with โค by GitHub

An effective way of learning about a new framework is to look into the rules that are part of the system. These rules are also referred to as the "best practices" of a given framework. These guardrails describe good behavior from the perspective of the creators. However, best practices alone aren't effective - they also need to be enforced.

One way to enforce good behavior is to use static analysis tools like Lint. It's a popular tool that exists across many programing languages and frameworks. Since the name of this site is JetpackCompose.app, we will zoom in and focus on Jetpack Compose. As I was trying to understand what good behavior in Compose looks like, I asked myself a simple question-

Where can I even find the list of Lint rules?

To answer this question, my first instinct was to dig through the source code on Android Code Search. While this is the right place to search for this information, it's painful to dig through all the results. Wouldn't it be nice if there was a consolidated list of all Lint rules that are being exposed by Compose?

Android Code Search

Thankfully, I was lucky to go to Google I/O this year and bring up this topic with the creator of Android Lint - Tor Norbye. It would be fair to say that I don't know anyone on this planet that's more excited about Lint than Tor. As soon as I asked my question, Tor hurriedly removed his laptop from his backpack, and showed me something that completely blew my mind.

JetpackCompose.app Job Board

Find the best Android jobs in world-class companies. Here are some featured jobs from the job board

It's worth mentioning that Google released Android Lint Documentation a couple years ago. This was after Android developers spent a decade trying to figure out how Lint worked on their own. These guides explained how one could configure Lint and write custom Lint rules. I was familiar with these guides and thought it was a positive addition to the ecosystem.

Lint Documentation

Here is where I let you in on a little secret because you are a part of the JetpackCompose.app community ๐Ÿ˜‰ โค๏ธ There's a not so popular section on that site called Issue Documentation. It contains a consolidated index of all Android Lint rules that are either built-in or ship with one of the androidx libraries. This is a powerful mechanism to discover all the Lint rules that are at play in your codebase. You can make this list more useful by ordering "By vendor". You can see a categorized break up of the Lint rules based on the artifact it belongs to.

Lint Issue Index

In the gif above, I searched for "Jetpack Compose" on the issue documentation page and was able to see all the rules that the Jetpack Compose libraries ship by default. You get a lot more information about each rule if you click on it. Here's the rule that enforces the correct usage of the Modifier parameter in a composable function.

Lint Rule Detail

Enforcements >>> Best Practices

Something that I've been preaching on my team as we embrace Jetpack Compose is Enforcements >>> Best Practices. This is critical as it ensures there's consistency across your codebase. It also acts as a forcing function for good behavior. Moreover, you don't want to rely on humans to make good decisions - we are a flawed species after all ๐Ÿ˜…

Want Jetpack Compose related content & tools straight in your inbox?
Subscribe for exclusive content and early access to content ๐Ÿ‘‡
JetpackCompose.app Mascot
No spam whatsoever and one click unsubscribe if you don't like it.

In spirit of this mantra, I decided to audit the existing Lint rules and noticed that a lot of these rules were Warnings instead of Errors. It means that in most cases, you will be allowed to ignore these rules and merge your change. Thankfully, there's a way to tune this behavior to your liking-

<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <issue id="ID_OF_LINT_RULE" severity="SEVERITY_OF_ISSUE" />
</lint>

You can create(if it doesn't already exist) a file called lint.xml in your codebase and configure the behavior of the lint rules that you'd like to override. For example, the ComposableNaming lint rule enforces that @Composable functions without a return type should use similar naming to classes, starting with an uppercase letter and ending with a noun. However, its currently a warning and I'd like this to be an error in my codebase. So I will use the lint.xml file and make the following change-

<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <issue id="ComposableNaming" severity="error" />
</lint>

Additionally, suppressing one of these lint rules across your codebase is just as easy - simply pass ignore as the severity value.

<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <issue id="ComposableNaming" severity="ignore" />
</lint>

Finally, you might be wondering which lint rules I recommend updating? Since I love my readers so much, I decided to do a thorough audit of the Compose lint rules and am happy to give you a starting point ๐Ÿ™Œ๐Ÿป I would stronly encourage you to read up about the lint rules before you add these changes to your codebase.

<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <issue id="FrequentlyChangedStateReadInComposition" severity="error" />
    <issue id="ComposableModifierFactory" severity="error" />
    <issue id="ModifierFactoryExtensionFunction" severity="error" />
    <issue id="ModifierFactoryReturnType" severity="error" />
    <issue id="ModifierParameter" severity="error" />
    <issue id="UnnecessaryComposedModifier" severity="error" />
    <issue id="InvalidColorHexValue" severity="error" />
    <issue id="MissingColorAlphaChannel" severity="error" />
    <issue id="ComposableLambdaParameterNaming" severity="error" />
    <issue id="ComposableNaming" severity="error" />
    <issue id="CompositionLocalNaming" severity="error" />
    <issue id="MutableCollectionMutableState" severity="error" />
</lint>

I'm confident that you are going to see some violations that you didn't realize you were making ๐Ÿ˜…

Closing thoughts

Learning about the rules of a new framework is an effective way to learn about its best practices. Some of the lint rules I discovered were super interesting and taught me a lot about some of the best practices in Compose that weren't broadcasted explicitly in the official Compose documentation.

One final piece of advice I want to leave you with is the fact that adding guardrails early in the process saves you a lot of pain in the long run. We are still early in our Jetpack Compose journey and so it would be wise to invest in tooling that not only educates our teams about best practices but also enforce them.


Vinay Gaba is a Google Developer Expert for Android. He's a Tech Lead at Airbnb and is responsible for UI Infra and Design Systems on Android. Prior to Airbnb, Vinay worked at Snapchat, Spotify, and Deloitte and got his Masters in Computer Science from Columbia University. He has been working on Android for over a decade.
Want Jetpack Compose related content & tools straight in your inbox?
Subscribe for exclusive content and early access to content ๐Ÿ‘‡
JetpackCompose.app Mascot
No spam whatsoever and one click unsubscribe if you don't like it.