Recommended guidelines for @Composable in Jetpack Compose

Breno Mascarenhas
3 min readFeb 22, 2024

--

Hi everyone, today I’m going to talk with you about some recommendations that Google defines for developers who create @Composable Components in general. First of all, I want to mention that the documentation that I’m following is used as guidelines for the Jetpack Compose framework itself, and it’s recommended for every external library that targets to exist with Jetpack Compose. They know that in some cases, some strong organizational priorities and norms are established and for app development, some of the recommendations should be followed. I’m going to pass through a few of them in this article, and I recommend you take some time to read the official document.

BasicComponent vs Component

Consider using Basic prefix for components that provide barebones functionality with no decoration and/or with no design system-based visual opinions. The Component name without the prefix can represent components that are ready to use and are decorated according to some design specification. For example:

// component that has no decoration, but basic functionality
@Composable
fun BasicTextField(
value: TextFieldValue,
onValueChange: (TextFieldValue) -> Unit,
modifier: Modifier = Modifier,
...
)

// ready to use component with decorations
@Composable
fun TextField(
value: TextFieldValue,
onValueChange: (TextFieldValue) -> Unit,
modifier: Modifier = Modifier,
...
)

Design, Usecase, or Company/Project specific prefixes

We should avoid CompanyName like GoogleButton, or Module like WearButton prefixes where possible and consider use-case or domain-specific names if needed.

If you are wrapping existing components, consider names that are derived from the use case first:

// This button is called ContainedButton in the spec
// It has no prefix because it is the most common one
@Composable
fun Button(...) {}

// Other variations of buttons below:
@Composable
fun OutlinedButton(...) {}
@Composable
fun TextButton(...) {}

Parameters order

This one I think is just a good nit that would improve your code readability. The order of parameters in a component must be as follows:

  1. Required parameters.
  2. Single modifier: Modifier = Modifier .
  3. Optional parameters.
  4. (optional) trailing @Composable lambda.

Why that’s the recommendation? They explain each one of them:

  1. Required parameters. They don’t have default values and the developer is required to pass the values for those parameters in order to use the components. Coming first, they allow the devs to set them without using name parameters, and focus on it initially.
  2. modifier: Modifier = Modifier. There should be only one modifier and it should be applied to the root-most layout in the implementation. Usually, the developer needs to make some customizations, and that should come after the required ones.
  3. Optional parameters. They do have default values that will be used if not overridden by the developer, and the dev doesn’t need to make any choice when creating the Component.
  4. (optional) trailing @Composable lambda representing the main content of the component, usually named as content.

Let’s take a look at the example:

@Composable
fun Icon(
// image bitmap and contentDescription are required
// bitmap goes first since it is the required data for the icon
bitmap: ImageBitmap,
// contentDescription follows as required, but it is "metadata", so
// it goes after the "data" above.
contentDescription: String?,
// modifier is the first optional parameter
modifier: Modifier = Modifier,
// tint is optional, default value uses theme-like composition locals
// so it's clear where it's coming from and to change it
tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
)

That’s all I want to share with you this time, for the next article I’m going to talk about the slots API. I’ve chosen some of the recommendations and summarized them just to make this article short and quick to read. Hope you enjoy it and let your comments if you want to discuss any of these points above.

--

--