# Getting Started

The **Compose UI Components** library includes pre-built Jetpack Compose components that let you easily load and display data from the Stream Chat API, without much code.

> Not using Compose yet? Check out our XML-based [UI Components](/chat/docs/sdk/android/v6/ui/overview/).

First things first, you have to initialize the `ChatClient` in your application.
This is the main entry point for all the chat functionalities.
Typically you would initialize the `ChatClient` in your `Application` class.

```kotlin
ChatClient.Builder("YOUR_API_KEY", context)
    // Set other configurations
    .build()

// Static reference to initialized client
val client = ChatClient.instance()
```

## Connecting a User

Once you have the `ChatClient` initialized, you can connect a user to the chat.

Let's say you have a `User` model:

```kotlin
val user = User(
    id = "bender",
    name = "Bender",
    image = "https://bit.ly/321RmWb",
)
```

Then you can call the `connectUser` method with either a JWT token or a `TokenProvider` to connect the user to the chat.

Here is an example of how to connect a user to the chat with a JWT token:

```kotlin
val token = "CHAT_USER_TOKEN"
client.connectUser(user, token).enqueue { result ->
    when (result) {
        is Result.Success -> {
            // Logged in
            val loggedInUser: User = result.value.user
            val connectionId: String = result.value.connectionId
        }
        is Result.Failure -> {
            // Handle error
            val error = result.value

        }
    }
}
```

Here is an example of how to connect a user to the chat with a `TokenProvider`:

```kotlin
val tokenProvider = object : TokenProvider {
    // Make a request to your backend to generate a valid token for the user.
    // It is expected that "yourTokenService.getToken" never throws an exception.
    // If the token cannot be loaded, it should return an empty string.
    override fun loadToken(): String = yourTokenService.getToken(user)
}
client.connectUser(user, tokenProvider).enqueue { /* ... */ }
```

<admonition type="note">

Please ensure that the `TokenProvider.loadToken` implementation never throws an exception.
If the token cannot be loaded, it should return an empty string.

</admonition>

## Lifecycle Management

Most commonly, you would want to call `ChatClient#connectUser` when the user logs in and `ChatClient#disconnect` when the user logs out.

<admonition type="note">

Please take into account that the `ChatClient` cannot survive a process death.
When the app process gets killed with the logged-in user, you will need to call `ChatClient#connectUser` again to re-establish the connection.

</admonition>

To handle those scenarios, you could define some `UserRepository` in your application that would be responsible for storing the logged-in user until the user logs out.

```kotlin
interface UserRepository {
    fun getCurrentUser(): User?
    fun setCurrentUser(user: User)
    fun clearCurrentUser()
}
```

<admonition type="note">

Please note that the `UserRepository` is just an example.
You can name it whatever you want and use any storage mechanism for the implementation (for example `SharedPreferences`, `Room`, etc.).
The main idea is to have a storage which will be able to provide the logged-in user when the app restarts after a process death.

</admonition>

Then when the user logs in, you would call `ChatClient#connectUser` and store the user in the `UserRepository`.

```kotlin
val user = User(/* ... */)
client.connectUser(user, tokenProvider).enqueue { result ->
    if (result is Result.Success) {
        userRepository.setCurrentUser(result.value.user)
    } else if (result is Result.Failure) {
        // Handle error
    }
}
```

When the user logs out, you would call `ChatClient#disconnect` and clear the user from the `UserRepository`.

```kotlin
client.disconnect(flushPersistence = true).enqueue { result ->
    userRepository.clearCurrentUser()
    // Handle result
}
```

Please note that you should also call `ChatClient#connectUser` when the Application restarts after a process death and there is a logged-in user in the `UserRepository`.

```kotlin
val user = userRepository.getCurrentUser()
if (user != null) {
    client.connectUser(user, tokenProvider).enqueue { /* ... */ }
}
```

## UI Components

| Channels Screen (Light Theme)                                                 | Messages Screen (Light Theme)                                                 |
| ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| ![Channels](@chat-sdk/android/v6/_assets/compose_channels_screen_example.png) | ![Messages](@chat-sdk/android/v6/_assets/compose_messages_screen_example.png) |

| Channels Screen (Dark Theme)                                                       | Messages Screen (Dark Theme)                                                       |
| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| ![Channels](@chat-sdk/android/v6/_assets/compose_channels_screen_example_dark.png) | ![Messages](@chat-sdk/android/v6/_assets/compose_messages_screen_example_dark.png) |

This library builds on top of the offline library and provides three types of components:

- **Screen components**: Fully built screens that work out-of-the-box, but offer much more limited customization.
- **Bound components**: Fully built components that represent a part of the screen and are **bound** to `ViewModels` that we provide, for business logic, events, and state handling. These provide extensive behavior and UI customization.
- **Stateless components**: Simple components that rely on external state and know nothing about our `ViewModels`. Fully customizable.

The [sample app](#sample-app) showcases the Compose UI Components in action.

See the individual pages for these components to learn more about them.

**Channel components**:

- [Channels Screen](/chat/docs/sdk/android/v6/compose/channel-components/channels-screen/)
- [Channel List Header](/chat/docs/sdk/android/v6/compose/channel-components/channel-list-header/)
- [Channel List](/chat/docs/sdk/android/v6/compose/channel-components/channel-list/)
- [Channel Item](/chat/docs/sdk/android/v6/compose/channel-components/channel-item/)
- [Selected Channel Menu](/chat/docs/sdk/android/v6/compose/channel-components/selected-channel-menu/)

**Message components**:

- [Messages Screen](/chat/docs/sdk/android/v6/compose/message-components/messages-screen/)
- [Message List Header](/chat/docs/sdk/android/v6/compose/message-components/message-list-header/)
- [Message List](/chat/docs/sdk/android/v6/compose/message-components/message-list/)
- [Message Composer](/chat/docs/sdk/android/v6/compose/message-components/message-composer/)
- [Attachments Picker](/chat/docs/sdk/android/v6/compose/message-components/attachments-picker/)
- [Selected Message Menu](/chat/docs/sdk/android/v6/compose/message-components/selected-message-menu/)
- [Reactions](/chat/docs/sdk/android/v6/compose/message-components/selected-reactions-menu/)

**Utility components**

- [User Avatar](/chat/docs/sdk/android/v6/compose/utility-components/user-avatar/)
- [Channel Avatar](/chat/docs/sdk/android/v6/compose/utility-components/channel-avatar/)
- [Search Input](/chat/docs/sdk/android/v6/compose/utility-components/search-input/)

## Checklist

For a successful integration of our Compose UI Components, follow these steps:

1. Set up your project to work with Jetpack Compose, as per the [official documentation](https://developer.android.com/jetpack/compose/setup).
2. Dependency. Add the dependency to your app, as described on the [Dependencies](/chat/docs/sdk/android/v6/basics/dependencies#compose-ui-components/) page.
3. Set up the `ChatClient`. Learn how to initialize the ChatClient in the [Chat Client documentation](/chat/docs/android/#chat-client/).
4. Handle user connection. Read how to connect a user in the [Connecting the User guide](/chat/docs/android/init_and_users/#connecting-the-user/) and learn about User Tokens in the [Tokens and Authentication guide](/chat/docs/android/tokens_and_authentication/).
5. State and Offline. Using the `StatePlugin` is mandatory if you want to use our UI Components. Read the [State Overview](/chat/docs/sdk/android/v6/client/guides/state-overview/) page for more information. Also, consider adding [offline support](/chat/docs/sdk/android/v6/client/guides/offline-support/) for better UX.

<admonition type="note">

If you're looking to explore the setup and our components in a step-by-step way, check out our [Compose In-App Messaging Tutorial](https://getstream.io/chat/compose/tutorial/). Also, check-out our [sample app](#sample-app).

</admonition>

## ViewModels

Our **bound components** require a `ViewModel` to connect to for state and event handling. Some of our components build the `ViewModel` by default, but you'll likely want to build your own instances to gain more control over their lifecycle.

These are Jetpack [ViewModels](https://developer.android.com/topic/libraries/architecture/viewmodel), so they allow the components to retain data across configuration changes. It's your responsibility to create these in the correct scope, usually in a Fragment or Activity.

For example, if you want to add the `MessageList` component to your UI, you can do it like so:

```kotlin
// 1
val factory by lazy {
    MessagesViewModelFactory(
        context = this,
        chatClient = ChatClient.instance(),
        channelId = "messaging:123",
        enforceUniqueReactions = true,
        messageLimit = 30
    )
}

// 2
val listViewModel: MessageListViewModel by viewModels { factory }

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // 3
    setContent {
        ChatTheme {
            MessageList(
                modifier = Modifier
                    .padding(8.dp)
                    .fillMaxSize(),
                viewModel = listViewModel // 4
            )
        }
    }
}
```

1. Create the `ViewModel` factory, providing any necessary parameters.
2. Build the `ViewModel`, using the Android `ViewModel` APIs and the `factory` you created.
3. Set the content of your `Activity` or `Fragment` and call the `MessageList` component.
4. Pass in the `ViewModel` to the component.

By passing in the `ViewModel`, the component knows where to fetch the data from and where to delegate various events, like selecting a message or tapping on a thread reply.

You can learn more about each component's setup and usages on their individual pages.

## Sample App

The [Compose UI Components sample app](https://github.com/GetStream/stream-chat-android/tree/v6/stream-chat-android-compose-sample) is an open-source and fully functional messaging application that lets you explore and test our API. It features channels, threads, reactions, various attachments, UI updates and offline storage, all built using our Compose UI Components and the offline library.

## Customization

Our Compose UI Components offer different ways of customization:

- **Behavior**: Through event handlers for clicks, taps, dismiss requests and more.
- **Appearance**: Through different parameters for shapes, colors or a Compose `Modifier`, you can customize the component appearance.
- **Content**: Some components provide [slot APIs](https://developer.android.com/jetpack/compose/layouts/basics#slot-based-layouts), composable function parameters that let you define (or override) their internal content.
- **Design style**: By using our `ChatTheme` component as the root of all of your UI, you can define the colors, typography, shapes, attachment factories, reaction types and various other things our components use. Through this, you can apply your own design style to all Compose UI Components.

To learn what level of customization each component exposes, check out their respective documentation pages. If you want to learn about general customization, read our [ChatTheme](/chat/docs/sdk/android/v6/compose/general-customization/chat-theme/) page.


---

This page was last updated at 2026-04-17T17:33:30.547Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/android/v6/compose/overview/](https://getstream.io/chat/docs/sdk/android/v6/compose/overview/).