Beginner Tips for Creating Composables with Jetpack Compose

So, you’re creating your first composable in Jetpack Compose. It’s easy enough, but it is easier to write more complex and unreadable code as you build out your first UI. Here are some tips that are easy to apply to your first composable.

Pass in custom modifiers.

When designing custom composables in Jetpack Compose, it’s recommended to grant users the ability to apply custom modifiers to your composable. To facilitate this, you can offer a default modifier and allow users to pass in their custom modifiers. If a user doesn’t specify a modifier, you can apply the default modifier to the outermost composable. This approach enhances the flexibility and customization options for your composable components.

fun CustomTextField(modifier: Modifier = Modifier.fillMaxSize()) {
    var text by remember { mutableStateOf(TextFieldValue()) }

        value = text,
        onValueChange = {
            text = it
        textStyle = TextStyle(fontSize = 20.sp, color = Color.Black),
        modifier = modifier.background(Color.LightGray) // Here we pass a Modifier to the BasicTextField

fun CustomTextFieldPreview() {
    CustomTextField(modifier = Modifier
        .padding(16.dp)) // Example of passing a modifier with padding

Set defaults for optional parameters.

It’s common in many programming languages and frameworks to declare optional parameters. You can then assign values conditionally if none are provided. Kotlin simplifies this process by enabling you to establish default values. Rather than checking for nullability and manually assigning values within the component, leverage Kotlin’s default value feature. This approach enhances code clarity by clearly defining the defaults for all your composables.

fun CustomText(
    text: String,
    color: Color = Color.Black,
    fontSize: Int = 16,
    modifier: Modifier = Modifier
) {
    val density = LocalDensity.current.density
    Column(modifier = modifier) {
            text = text,
            color = color,
            fontSize = (fontSize * density).sp

Use a noun-based naming convention.

When naming your composable components in Jetpack Compose, use nouns that succinctly describe the purpose and representation of the composable. This naming convention promotes clarity and maintainability in your codebase. It does this by ensuring that the name reflects the intended role of the composable within your app’s user interface. Additionally, using descriptive nouns helps other developers understand the purpose and usage of your composables when they review or collaborate on your code.

Avoid using unnecessary composable wrappers.

Do you really need that? A common oversight we made was occasionally using more wrapping layers around our composables than necessary. It’s important to remember that every composable offers a modifier where you can tailor it to your specific requirements. For instance, there’s no need to consistently enclose a composable within a Box when you can conveniently apply those modifiers directly to the enclosing Column or Row. This practice streamlines your code and makes it more efficient.

Know when to reinvent the wheel.

Jetpack Compose and Material 3 provide great out-of-the-box functionality for composables that allow you to build up screens really quickly. Make sure you check to see if there is a composable in Material 3 that fits your needs, but caution, sometimes making a composable work the way you want is more difficult than creating a custom one.

In the context of incorporating intricate and unique animations, there are instances where the Material 3 composable may not offer built-in support for custom animations. In such cases, opting to design a custom component could be the most suitable approach. Similarly, when crafting custom buttons, leveraging the modifier parameter to incorporate an onClick handler is a straightforward option. However, when faced with challenges in styling Material buttons, it’s advisable to create a custom clickable component to achieve the desired visual and functional results.


Join the conversation

Your email address will not be published. Required fields are marked *