--- title: Custom Themes description: In this guide, you will learn how to create fully custom themes and how to use them to maintain consistent styling in your Compose apps. --- ## Create a theme To create a theme, use the `buildTheme { }` function. ```kotlin val MyTheme = buildTheme { } ``` It returns a theming `@Composable` that you can use to wrap your app with: ```kotlin @Composable fun App() { MyTheme { Box(Modifier.fillMaxSize()) { Text("My awesome app") } } } ``` The theming function we just created forwards any styling properties to its children. Children can access those properties using the `Theme` object. Those are usually **colors**, **typography**, **shapes** and anything you need to style your apps with. But we haven't defined any, so let's do that next: ## Customize your theme Let's define some colors. To do this, let's create a 'colors' **theme property**. Theme Properties hold a `Map` of **theme tokens**. This links the tokens to the actual values. ```kotlin val colors = ThemeProperty("colors") val background = ThemeToken("background") val onBackground = ThemeToken("on_background") val MyTheme = buildTheme { properties[colors] = mapOf( background to Color(0xFFFAFAFA), onBackground to Color(0XFF0C0A09), ) } ``` Compose Unstyled does not force the structure of your themes and does not come with default styling options that you will end up removing afterwards. You can create any kind of properties you need that fit your design needs. > Even though `buildTheme` is not a `@Composable` function, the scope it provides for defining your properties is. This is handy for when you need to prepare properties asynchronously without blocking the UI thread (such as loading fonts) and creating [dynamic themes](dynamic-themes.md). ## Styling your app using your theme We can now style our app using the `Theme` object to access the values for each token: ```kotlin @Composable fun App() { MyTheme { Box(Modifier.fillMaxSize().background(Theme[colors][background])) { Text("My awesome app", color = Theme[colors][onBackground]) } } } ``` And that's the gist. You now know how to create custom themes, customize them with the properties you need, and use them in your app. ## Default properties Compose Unstyled themes come with some default properties you can set to style your app. ### Content Color Sets the default `Color` used by all Unstyled [components](/docs/compose-unstyled/components) to render their content. ```kotlin val MyTheme = buildTheme { defaultContentColor = Color(0XFF0C0A09) } ``` ### Text Style Sets the default `TextStyle` used by [Text](text.md) and [TextField](textfield.md) components to render their text contents. ```kotlin val MyTheme = buildTheme { defaultTextStyle = TextStyle( fontWeight = FontWeight.Medium, fontSize = 16.sp ) } ``` ### Indication Sets the default `Indication` used by interactive elements such as buttons and clickables. This is the same as providing an `Indication` value for the `LocalIndication`. ```kotlin import com.composeunstyled.theme.rememberColoredIndication val MyTheme = buildTheme { defaultIndication = rememberColoredIndication( hoveredColor = Color.White.copy(alpha = 0.3f), pressedColor = Color.White.copy(alpha = 0.5f), focusedColor = Color.Black.copy(alpha = 0.1f), ) } ``` ### TextSelectionColors Controls the colors used by text and text fields for text selection. This is the same as providing a `TextSelectionColors` value for the `LocalTextSelectionColors`. ```kotlin val MyTheme = buildTheme { defaultTextSelectionColors = TextSelectionColors( handleColor = Color.Blue, backgroundColor = Color.Blue.copy(alpha = 0.4f) ) } ``` ## Debugging your theme Unstyled will throw an exception when you try to access a token that is not present in the current theme. To make it simpler to debug such scenarios, it is highly recommended to name your themes when you create them. By doing so, Unstyled will provide descriptive error messages when you try to access a token that does not exist during runtime. ```kotlin val LightTheme = buildTheme { name = "LightTheme" } ```