
Opinionated Material 3–native component set with zero-config theming, editorial Public Sans scale, warm brand palette, accessibility defaults, tokenized spacing/shapes/typography, and 29 ready UI components.
Opinionated, Material You-native Jetpack Compose components that look great with zero styling work.
Documentation · Components · Theming · Changelog · Contributing
FormaUI is a Jetpack Compose component library for Android, built as a themed layer on top of Material 3 — production-ready components with better defaults, so you can ship fast instead of building a design system from scratch.
The positioning wedge: Unlike headless/unstyled toolkits (e.g. Composables UI — "Compose without Material"), FormaUI is deliberately opinionated and Material 3-native. Components ship with a distinct brand look — Public Sans with an editorial display scale over a warm-editorial palette — yet still feel like the Material 3 you already know (and Material You dynamic color is one flag away), so anyone productive in Compose Material 3 is productive in FormaUI within minutes.
modifier, colors, shape, and more where it matters.FormaTheme(dynamicColor = true) on Android 12+.Pre-1.0. All public APIs are annotated
@ExperimentalFormaUiApiwhile the surface stabilizes. Expect breaking changes before1.0.0.
FormaUI publishes to Maven Central under the dev.formaui group. Add it to your version catalog / Gradle build:
dependencies {
implementation("dev.formaui:components:0.2.0") // components transitively brings in :core
// or depend on the theming engine alone:
// implementation("dev.formaui:core:0.2.0")
}
0.2.0is the current release. The Maven Central badge above always shows what is actually published.
Moved from
io.github.devsnackioin0.2.0. Releases up to0.1.0shipped under that group, before theformaui.devdomain was owned. Only the coordinate changed — imports were alwaysdev.formaui.*, so migrating is a one-line edit to your dependency. Relocation POMs keep old builds resolving, but the retired group gets no further releases.
Requirements: Android minSdk 24+, Kotlin 2.4.x, Material 3. Android is the only published target. The artifacts are built with Compose Multiplatform 1.11.x (org.jetbrains.compose), so they also work in a Compose Multiplatform app's Android source set; no other target is published.
Because the APIs are experimental pre-1.0, opt in where you use them:
@OptIn(ExperimentalFormaUiApi::class)
@Composable
fun MyScreen() { /* … */ }Wrap your app in FormaTheme and drop in components:
@OptIn(ExperimentalFormaUiApi::class)
@Composable
fun App() {
FormaTheme { // brand palette by default; pass dynamicColor = true for Material You on Android 12+
Column {
FormaButton(onClick = { /* … */ }) { Text("Get started") }
var query by remember { mutableStateOf("") }
FormaTextField(
value = query,
onValueChange = { query = it },
label = "Search",
)
FormaCard(variant = FormaCardVariant.Elevated) {
Text("Cards, chips, sheets, and 37 more — all themed to match.")
}
}
}
}FormaTheme layers FormaUI tokens on top of Material 3's ColorScheme:
@Composable
fun FormaTheme(
colorScheme: FormaColorScheme = FormaTheme.defaultColorScheme(),
typography: FormaTypography = FormaTheme.defaultTypography(),
shapes: FormaShapes = FormaTheme.defaultShapes(),
dynamicColor: Boolean = false, // brand palette by default; true = Material You on Android 12+
darkTheme: Boolean = isSystemInDarkTheme(), // force light/dark, or follow the system
content: @Composable () -> Unit,
)Read tokens anywhere inside the theme via FormaTheme.colorScheme, FormaTheme.typography, FormaTheme.shapes, and FormaTheme.spacing. Design tokens:
FormaSpacing — a 4dp grid (xxs 4 / xs 8 / sm 12 / md 16 / lg 24 / xl 32 / xxl 48 / section 96); components use these internally, never hardcoded dp.FormaShapes — corner tiers none / xs 4 / sm 6 / md 8 / lg 12 / xl 16 / pill / full.FormaTypography — an editorial Public Sans type scale plus a tabular-figures numeric style for financial/data display.FormaColorScheme — light + dark brand palettes, fully overridable.All 40 components (the 18 in the original Phase 1 scope, plus 22 extras), each with variants/states, KDoc, @Previews, and UI tests:
| Button — filled/outlined/text/elevated/tonal | TextField — outlined/filled, error/disabled, icons, helper text | Card — elevated/outlined/filled, header/content/footer, clickable |
| Chip — assist/filter/input/suggestion |
Badge — dot/numeric/overflow + FormaBadgedBox
|
Switch |
| Checkbox | RadioButton | Dialog — alert + full-screen |
| BottomSheet — modal | NavigationBar — with per-item badges | ListItem — one/two/three-line, slots, clickable |
| Avatar — initials/icon/image slot, sized | Divider — horizontal/vertical | LoadingIndicator — circular/linear, determinate/indeterminate |
| EmptyState — icon + title + description + action |
Snackbar — standard + action, FormaSnackbarHost
|
Slider |
| TopAppBar — small/center-aligned/medium/large | FloatingActionButton — small/regular/large + extended | IconButton — standard/filled/tonal/outlined |
| BottomAppBar — actions + optional FAB | DropdownMenu — items with leading/trailing icons | NavigationDrawer — modal, slot-based items |
| NavigationRail — with badges + optional header | SearchBar — docked + full-screen | SegmentedButton — single/multi-select |
| TabRow — primary/secondary, fixed/scrollable | Tooltip — plain + rich | ExposedDropdownMenu — autocomplete, editable/tap-to-select |
| DatePickerSheet — calendar + text-input, in a sheet | DateRangePickerSheet — start/end range, in a sheet | TimePickerSheet — clock dial + text input, in a sheet |
| RangeSlider — two-thumb, continuous/stepped | Carousel — multi-browse/uncontained, snapping | PullToRefresh — swipe-down refresh, indicator slot |
| SwipeToDismiss — per-direction, background slot | BarChart — gridlines, value labels, entry animation | DonutChart — arc segments, center slot, legend |
| LineChart — smooth/straight, area fill, markers |
A runnable showcase app demonstrates every component live, with light/dark and dynamic-color toggles:
./gradlew :sample:installDebug # with an emulator/device connected, then launch "FormaUI Sample"Or open the project in Android Studio and run the sample configuration. The sample screen is itself built entirely from FormaUI components — it doubles as a reference usage example.
core/ # Theming engine: FormaTheme, color/typography/spacing/shape tokens (zero FormaUI deps)
components/ # The 40 components (depends on :core)
sample/ # Runnable Android showcase app
build-logic/ # Gradle convention plugins
Targets: Android (the published artifact) and wasmJs (compiled for the live component previews embedded in the docs site).
FormaUI core and components are licensed under the Apache License 2.0.
Opinionated, Material You-native Jetpack Compose components that look great with zero styling work.
Documentation · Components · Theming · Changelog · Contributing
FormaUI is a Jetpack Compose component library for Android, built as a themed layer on top of Material 3 — production-ready components with better defaults, so you can ship fast instead of building a design system from scratch.
The positioning wedge: Unlike headless/unstyled toolkits (e.g. Composables UI — "Compose without Material"), FormaUI is deliberately opinionated and Material 3-native. Components ship with a distinct brand look — Public Sans with an editorial display scale over a warm-editorial palette — yet still feel like the Material 3 you already know (and Material You dynamic color is one flag away), so anyone productive in Compose Material 3 is productive in FormaUI within minutes.
modifier, colors, shape, and more where it matters.FormaTheme(dynamicColor = true) on Android 12+.Pre-1.0. All public APIs are annotated
@ExperimentalFormaUiApiwhile the surface stabilizes. Expect breaking changes before1.0.0.
FormaUI publishes to Maven Central under the dev.formaui group. Add it to your version catalog / Gradle build:
dependencies {
implementation("dev.formaui:components:0.2.0") // components transitively brings in :core
// or depend on the theming engine alone:
// implementation("dev.formaui:core:0.2.0")
}
0.2.0is the current release. The Maven Central badge above always shows what is actually published.
Moved from
io.github.devsnackioin0.2.0. Releases up to0.1.0shipped under that group, before theformaui.devdomain was owned. Only the coordinate changed — imports were alwaysdev.formaui.*, so migrating is a one-line edit to your dependency. Relocation POMs keep old builds resolving, but the retired group gets no further releases.
Requirements: Android minSdk 24+, Kotlin 2.4.x, Material 3. Android is the only published target. The artifacts are built with Compose Multiplatform 1.11.x (org.jetbrains.compose), so they also work in a Compose Multiplatform app's Android source set; no other target is published.
Because the APIs are experimental pre-1.0, opt in where you use them:
@OptIn(ExperimentalFormaUiApi::class)
@Composable
fun MyScreen() { /* … */ }Wrap your app in FormaTheme and drop in components:
@OptIn(ExperimentalFormaUiApi::class)
@Composable
fun App() {
FormaTheme { // brand palette by default; pass dynamicColor = true for Material You on Android 12+
Column {
FormaButton(onClick = { /* … */ }) { Text("Get started") }
var query by remember { mutableStateOf("") }
FormaTextField(
value = query,
onValueChange = { query = it },
label = "Search",
)
FormaCard(variant = FormaCardVariant.Elevated) {
Text("Cards, chips, sheets, and 37 more — all themed to match.")
}
}
}
}FormaTheme layers FormaUI tokens on top of Material 3's ColorScheme:
@Composable
fun FormaTheme(
colorScheme: FormaColorScheme = FormaTheme.defaultColorScheme(),
typography: FormaTypography = FormaTheme.defaultTypography(),
shapes: FormaShapes = FormaTheme.defaultShapes(),
dynamicColor: Boolean = false, // brand palette by default; true = Material You on Android 12+
darkTheme: Boolean = isSystemInDarkTheme(), // force light/dark, or follow the system
content: @Composable () -> Unit,
)Read tokens anywhere inside the theme via FormaTheme.colorScheme, FormaTheme.typography, FormaTheme.shapes, and FormaTheme.spacing. Design tokens:
FormaSpacing — a 4dp grid (xxs 4 / xs 8 / sm 12 / md 16 / lg 24 / xl 32 / xxl 48 / section 96); components use these internally, never hardcoded dp.FormaShapes — corner tiers none / xs 4 / sm 6 / md 8 / lg 12 / xl 16 / pill / full.FormaTypography — an editorial Public Sans type scale plus a tabular-figures numeric style for financial/data display.FormaColorScheme — light + dark brand palettes, fully overridable.All 40 components (the 18 in the original Phase 1 scope, plus 22 extras), each with variants/states, KDoc, @Previews, and UI tests:
| Button — filled/outlined/text/elevated/tonal | TextField — outlined/filled, error/disabled, icons, helper text | Card — elevated/outlined/filled, header/content/footer, clickable |
| Chip — assist/filter/input/suggestion |
Badge — dot/numeric/overflow + FormaBadgedBox
|
Switch |
| Checkbox | RadioButton | Dialog — alert + full-screen |
| BottomSheet — modal | NavigationBar — with per-item badges | ListItem — one/two/three-line, slots, clickable |
| Avatar — initials/icon/image slot, sized | Divider — horizontal/vertical | LoadingIndicator — circular/linear, determinate/indeterminate |
| EmptyState — icon + title + description + action |
Snackbar — standard + action, FormaSnackbarHost
|
Slider |
| TopAppBar — small/center-aligned/medium/large | FloatingActionButton — small/regular/large + extended | IconButton — standard/filled/tonal/outlined |
| BottomAppBar — actions + optional FAB | DropdownMenu — items with leading/trailing icons | NavigationDrawer — modal, slot-based items |
| NavigationRail — with badges + optional header | SearchBar — docked + full-screen | SegmentedButton — single/multi-select |
| TabRow — primary/secondary, fixed/scrollable | Tooltip — plain + rich | ExposedDropdownMenu — autocomplete, editable/tap-to-select |
| DatePickerSheet — calendar + text-input, in a sheet | DateRangePickerSheet — start/end range, in a sheet | TimePickerSheet — clock dial + text input, in a sheet |
| RangeSlider — two-thumb, continuous/stepped | Carousel — multi-browse/uncontained, snapping | PullToRefresh — swipe-down refresh, indicator slot |
| SwipeToDismiss — per-direction, background slot | BarChart — gridlines, value labels, entry animation | DonutChart — arc segments, center slot, legend |
| LineChart — smooth/straight, area fill, markers |
A runnable showcase app demonstrates every component live, with light/dark and dynamic-color toggles:
./gradlew :sample:installDebug # with an emulator/device connected, then launch "FormaUI Sample"Or open the project in Android Studio and run the sample configuration. The sample screen is itself built entirely from FormaUI components — it doubles as a reference usage example.
core/ # Theming engine: FormaTheme, color/typography/spacing/shape tokens (zero FormaUI deps)
components/ # The 40 components (depends on :core)
sample/ # Runnable Android showcase app
build-logic/ # Gradle convention plugins
Targets: Android (the published artifact) and wasmJs (compiled for the live component previews embedded in the docs site).
FormaUI core and components are licensed under the Apache License 2.0.