
Enables dynamic theming and customization of UI components, facilitating easy switching of themes and colors for a more personalized user interface experience.
This library provides following main features:
MaterialTheme
[!NOTE] All features are splitted into separate modules, just include the modules you want to use!
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| Module | android | iOS | windows | macOS | wasm | Notes |
|---|---|---|---|---|---|---|
| core | ✅ | ✅ | ✅ | ✅ | ✅ | provides all the basic ComposeThemer classes to use and apply Themes |
| modules-picker | ✅ | ✅ | ✅ | ✅ | ✅ | provides states and composables to create a theme picker UI |
| modules-defaultpicker | ✅ | ✅ | ✅ | ✅ | ✅ | provides a default theme picker UI |
| themes-flatui | ✅ | ✅ | ✅ | ✅ | ✅ | provides a list of themes based on the 20 flatui colors (each one in 5 variations) |
| themes-material500 | ✅ | ✅ | ✅ | ✅ | ✅ | provides a list of themes based on the 19 material500 colors (each one in 5 variations) |
| themes-metro | ✅ | ✅ | ✅ | ✅ | ✅ | provides a list of themes based on the 20 metro colors (each one in 5 variations) |
| Dependency | Version |
|---|---|
| Kotlin | 2.4.0 |
| Jetbrains Compose | 1.11.1 |
| Jetbrains Compose Material3 | 1.9.0 |
Define the dependencies inside your libs.versions.toml file.
[versions]
composethemer = "<LATEST-VERSION>"
[libraries]
composethemer-core = { module = "io.github.mflisar.composethemer:core", version.ref = "composethemer" }
composethemer-modules-picker = { module = "io.github.mflisar.composethemer:modules-picker", version.ref = "composethemer" }
composethemer-modules-defaultpicker = { module = "io.github.mflisar.composethemer:modules-defaultpicker", version.ref = "composethemer" }
composethemer-themes-flatui = { module = "io.github.mflisar.composethemer:themes-flatui", version.ref = "composethemer" }
composethemer-themes-material500 = { module = "io.github.mflisar.composethemer:themes-material500", version.ref = "composethemer" }
composethemer-themes-metro = { module = "io.github.mflisar.composethemer:themes-metro", version.ref = "composethemer" }And then use the definitions in your projects build.gradle.kts file like following:
implementation(libs.composethemer.core)
implementation(libs.composethemer.modules.picker)
implementation(libs.composethemer.modules.defaultpicker)
implementation(libs.composethemer.themes.flatui)
implementation(libs.composethemer.themes.material500)
implementation(libs.composethemer.themes.metro)Simply add the dependencies inside your build.gradle.kts file.
val composethemer = "<LATEST-VERSION>"
implementation("io.github.mflisar.composethemer:core:${composethemer}")
implementation("io.github.mflisar.composethemer:modules-picker:${composethemer}")
implementation("io.github.mflisar.composethemer:modules-defaultpicker:${composethemer}")
implementation("io.github.mflisar.composethemer:themes-flatui:${composethemer}")
implementation("io.github.mflisar.composethemer:themes-material500:${composethemer}")
implementation("io.github.mflisar.composethemer:themes-metro:${composethemer}")You should do this once only, e.g. in your Application class.
// register all themes that you want to use (our just a subset of them, even a single one is enough)
val allThemes: List<ComposeTheme.Theme> =
DefaultThemes.getAllThemes() +
MetroThemes.getAllThemes() +
FlatUIThemes.getAllThemes() +
Material500Themes.getAllThemes()
ComposeTheme.register(*allThemes.toTypedArray())// create a state that holds the current theme settings
val baseTheme = rememberSaveable { mutableStateOf(ComposeTheme.BaseTheme.System) }
val contrast = rememberSaveable { mutableStateOf(ComposeTheme.Contrast.Normal) }
val dynamic = rememberSaveable { mutableStateOf(false) }
val theme = rememberSaveable { mutableStateOf(ThemeDefault.Theme.id) } // id of the current theme
val state = ComposeTheme.State(baseTheme, contrast, dynamic, theme)
// use ComposeTheme instead of MaterialTheme
ComposeTheme(state = state) {
// app content
}On android you can use ComposeTheme to set the status bar and navigation bar colors based on the current theme.
ComposeTheme(
state = state
) {
// set the color that you use behind the status bar and navigation bar (e.g. primary toolbar + surface bottom navigation)
val statusBarColor = ...
val navigationBarColor = ...
// UpdateEdgeToEdgeDefault...helper function to easily enable edgeToEdge
// SystemBarStyle also offers some extensions (statusBar, navigationBar, transparent) that can be used
// this app draws a bottom navigation behind the navigation bar in portrait only, in landscape mode it doesn't
val landscape = LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE
val isDark = state.base.value.isDark()
UpdateEdgeToEdgeDefault(
activity = this,
themeState = state,
statusBarColor = statusBarColor,
navigationBarColor = if (landscape) {
SystemBarStyle.defaultScrim(resources, isDark)
} else navigationBarColor,
isNavigationBarContrastEnforced = landscape
)
}A full demo is included inside the demo module, it shows nearly every usage with working examples.
Check out the API documentation.
You can find more libraries (all multiplatform) of mine that all do work together nicely here.
This library provides following main features:
MaterialTheme
[!NOTE] All features are splitted into separate modules, just include the modules you want to use!
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| Module | android | iOS | windows | macOS | wasm | Notes |
|---|---|---|---|---|---|---|
| core | ✅ | ✅ | ✅ | ✅ | ✅ | provides all the basic ComposeThemer classes to use and apply Themes |
| modules-picker | ✅ | ✅ | ✅ | ✅ | ✅ | provides states and composables to create a theme picker UI |
| modules-defaultpicker | ✅ | ✅ | ✅ | ✅ | ✅ | provides a default theme picker UI |
| themes-flatui | ✅ | ✅ | ✅ | ✅ | ✅ | provides a list of themes based on the 20 flatui colors (each one in 5 variations) |
| themes-material500 | ✅ | ✅ | ✅ | ✅ | ✅ | provides a list of themes based on the 19 material500 colors (each one in 5 variations) |
| themes-metro | ✅ | ✅ | ✅ | ✅ | ✅ | provides a list of themes based on the 20 metro colors (each one in 5 variations) |
| Dependency | Version |
|---|---|
| Kotlin | 2.4.0 |
| Jetbrains Compose | 1.11.1 |
| Jetbrains Compose Material3 | 1.9.0 |
Define the dependencies inside your libs.versions.toml file.
[versions]
composethemer = "<LATEST-VERSION>"
[libraries]
composethemer-core = { module = "io.github.mflisar.composethemer:core", version.ref = "composethemer" }
composethemer-modules-picker = { module = "io.github.mflisar.composethemer:modules-picker", version.ref = "composethemer" }
composethemer-modules-defaultpicker = { module = "io.github.mflisar.composethemer:modules-defaultpicker", version.ref = "composethemer" }
composethemer-themes-flatui = { module = "io.github.mflisar.composethemer:themes-flatui", version.ref = "composethemer" }
composethemer-themes-material500 = { module = "io.github.mflisar.composethemer:themes-material500", version.ref = "composethemer" }
composethemer-themes-metro = { module = "io.github.mflisar.composethemer:themes-metro", version.ref = "composethemer" }And then use the definitions in your projects build.gradle.kts file like following:
implementation(libs.composethemer.core)
implementation(libs.composethemer.modules.picker)
implementation(libs.composethemer.modules.defaultpicker)
implementation(libs.composethemer.themes.flatui)
implementation(libs.composethemer.themes.material500)
implementation(libs.composethemer.themes.metro)Simply add the dependencies inside your build.gradle.kts file.
val composethemer = "<LATEST-VERSION>"
implementation("io.github.mflisar.composethemer:core:${composethemer}")
implementation("io.github.mflisar.composethemer:modules-picker:${composethemer}")
implementation("io.github.mflisar.composethemer:modules-defaultpicker:${composethemer}")
implementation("io.github.mflisar.composethemer:themes-flatui:${composethemer}")
implementation("io.github.mflisar.composethemer:themes-material500:${composethemer}")
implementation("io.github.mflisar.composethemer:themes-metro:${composethemer}")You should do this once only, e.g. in your Application class.
// register all themes that you want to use (our just a subset of them, even a single one is enough)
val allThemes: List<ComposeTheme.Theme> =
DefaultThemes.getAllThemes() +
MetroThemes.getAllThemes() +
FlatUIThemes.getAllThemes() +
Material500Themes.getAllThemes()
ComposeTheme.register(*allThemes.toTypedArray())// create a state that holds the current theme settings
val baseTheme = rememberSaveable { mutableStateOf(ComposeTheme.BaseTheme.System) }
val contrast = rememberSaveable { mutableStateOf(ComposeTheme.Contrast.Normal) }
val dynamic = rememberSaveable { mutableStateOf(false) }
val theme = rememberSaveable { mutableStateOf(ThemeDefault.Theme.id) } // id of the current theme
val state = ComposeTheme.State(baseTheme, contrast, dynamic, theme)
// use ComposeTheme instead of MaterialTheme
ComposeTheme(state = state) {
// app content
}On android you can use ComposeTheme to set the status bar and navigation bar colors based on the current theme.
ComposeTheme(
state = state
) {
// set the color that you use behind the status bar and navigation bar (e.g. primary toolbar + surface bottom navigation)
val statusBarColor = ...
val navigationBarColor = ...
// UpdateEdgeToEdgeDefault...helper function to easily enable edgeToEdge
// SystemBarStyle also offers some extensions (statusBar, navigationBar, transparent) that can be used
// this app draws a bottom navigation behind the navigation bar in portrait only, in landscape mode it doesn't
val landscape = LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE
val isDark = state.base.value.isDark()
UpdateEdgeToEdgeDefault(
activity = this,
themeState = state,
statusBarColor = statusBarColor,
navigationBarColor = if (landscape) {
SystemBarStyle.defaultScrim(resources, isDark)
} else navigationBarColor,
isNavigationBarContrastEnforced = landscape
)
}A full demo is included inside the demo module, it shows nearly every usage with working examples.
Check out the API documentation.
You can find more libraries (all multiplatform) of mine that all do work together nicely here.