Jetpack Compose Tutorial for Android: Getting Started

In this Jetpack Compose tutorial, you’ll learn to use the new declarative UI framework being developed by the Android team by creating a cookbook app. By Joey deVilla.

Leave a rating/review
Download materials
Save for later
Update note: Joey deVilla updated this tutorial for Android Studio Giraffe, Kotlin 1.9 and Android 14. Alex Sullivan wrote the original.

We’re at an exciting point in Android development. According to a survey of the mobile development ecosystem taken in late 2022 by the Mobile Native Foundation, half of Android developers are building apps with Jetpack Compose. The other half are building them “the old way.”

Operating systems evolve, and Android — the world’s most popular OS — is no exception. When a platform the size of Android makes a change this big, the first developers who embrace the change gain a significant advantage. With half the Android developers still waiting to make the leap, the time to learn Jetpack Compose is now.

What Is Jetpack Compose?

Released in July 2021, Jetpack Compose is a UI toolkit that updates the process of building Android apps. Instead of XML, you use Kotlin code to declaratively specify how the UI should look and behave in various states. You don’t have to worry how the UI moves among those states — Jetpack Compose takes care of that. You’ll find it familiar if you’re acquainted with declarative web frameworks such as React, Angular or Vue.

The Jetpack Compose approach is a significant departure from Android’s original XML UI toolkit, now called Views. Views was modeled after old desktop UI frameworks and dates to Android’s beginning. In Views, you use a mechanism such as findViewById() or view binding to connect UI elements to code. This imperative approach is simple but requires defining how the program moves among states and how the UI should look and behave in those states.

Note: If you are interested in learning more about Jetpack Compose, you can read our book on the subject by subscribing today.

Jetpack Compose is built with Kotlin, and it takes advantage of the features and design philosophy of Kotlin language. It’s designed for use in applications written in Kotlin. With Jetpack Compose, you no longer have to context-switch to XML when designing your app’s UI; you do everything in Kotlin.

In this tutorial, you’ll build two Jetpack Compose apps:

  • A simple test run app, which you’ll build from scratch, starting with FileNew.
  • A more complex cookbook app that will display a list of recipe cards containing images and text. You’ll build this using a starter project.

Your First Jetpack Compose App

Ensure you’re running the latest stable version of Android Studio. Both apps in this tutorial — the simple app you’re about to build and the cookbook app you’ll build afterward — were built using the Flamingo version of Android Studio. Lately, Google has been upgrading Android Studio at a furious pace, and the code below might not work on earlier versions.

Note: “Check for Updates” is your friend! On the macOS version of Android Studio, you’ll find it under the Android Studio menu. If you’re a Windows- or Linux-based Android Studio user, you’ll find it under the Help menu.

Once you’ve confirmed your Android Studio is up to date, launch it and select FileNewNew Project…. Depending on how you last resized the New Project window, you’ll either see something like this:

A small version of Android Studio’s New Project window

or this:

A wide version of Android Studio’s New Project window

Either way, you’ll see the first template in the list is for an Empty Activity project with the Jetpack Compose icon:

In the world of programming, where you have to state matters explicitly so a compiler can understand them, this is considered a subtle hint. You should infer that Jetpack Compose is expected to be the preferred way for building Android UIs going forward, and the sooner you learn it, the better.

Select the Jetpack Compose Empty Activity template and click Next. In the following New Project window, name the project My First Compose App and click the Finish button.

Hello, Android!

Once Android Studio finished building the project, run the app. You should see something like this:

Android phone emulator displaying the Hello Android! screen

To see what’s behind this particularly unexciting screen, open MainActivity.kt. It still contains a MainActivity class and an onCreate() method, and onCreate() still calls on its counterpart in MainActivity’s superclass, ComponentActivity.

What’s different is the rest of the code in onCreate(). When building Android UIs the old way — which is called ViewsonCreate() calls the setContentView() method and passes it the ID of the view’s XML file, which Android uses to render the onscreen elements. In Jetpack Compose, onCreate() calls a method named setContent(), and in the default project, it looks like this:

setContent {
  MyFirstComposeAppTheme {
  // A surface container using the 'background' color from the theme
      modifier = Modifier.fillMaxSize(),
      color = MaterialTheme.colorScheme.background
    ) {

setContent() takes a lambda as its parameter, and near the end of that lambda is a call to a method called Greeting(). You’ll find its definition immediately after the MainActivity class:

fun Greeting(name: String, modifier: Modifier = Modifier) {
   text = "Hello $name!",
   modifier = modifier

As you see, Greeting() is the method that determines what appears onscreen when you run the app. You should also notice the following elements of this method:

  • It’s annotated with @Composable. This informs the compiler that Greeting() is a composable function (or composable for short), which means it receives data and generates a UI element in response. One reason to make it clear that a function is composable is that composable functions can only be called by other composable functions. setContent() which calls Greeting() is a composable.
  • It has parameters. As a function, it has parameters (or, if you prefer, it takes arguments). That makes composables flexible, allowing you to pass state to them. If you’re familiar with programming in React, composable parameters are Jetpack Compose’s version of props.
  • It’s a Unit function. It has no return value. Instead, it causes a user interface element to be drawn onscreen. Functional programming language purists would call this a side effect; we Jetpack Composers prefer to say that composables emit UI elements.
  • Its name is a CapitalizedNoun. The convention is that composable function names are nouns capitalized in PascalCase. It helps distinguish composables from ordinary functions and methods, where the convention is to make their names verbs that use camelCase capitalization.
  • It contains a call to a method called Text(). Text() is one of Jetpack Compose’s built-in composables, and given a string, it emits a text view containing that string.