Architectural Layers of Jetpack Compose
Architectural Layers of Jetpack Compose
Jetpack Compose is structured as a layered, modular framework rather than a single monolithic toolkit. Each layer builds on top of lower level components, providing increasing levels of abstraction and convenience while maintaining flexibility for developers to opt into the right level of control for their use case. Understanding these layers helps when customizing components, optimizing performance, or building a custom design system. By the end of this lesson, you will be able to:
- Identify the four architectural layers: Runtime, UI, Foundation, and Material.
- Explain what each layer provides and what it depends on.
- Determine which layer to target when customizing or building new components.
- Inspect and fork Material components by understanding their internal composition.
- Minimize dependencies by importing only the modules you need in multi module projects.
Runtime Layer
The Runtime layer is the foundation of Compose. It includes the core primitives that make the declarative programming model work: @Composable, remember, mutableStateOf, SideEffect, and the snapshot state system. This layer provides the recomposition engine and state management but does not define any UI rendering.
You can use the Runtime layer independently to build reactive state management for non UI scenarios. Libraries that need Compose's reactivity without any rendering, such as state holders or reactive data layers, can depend on compose-runtime alone. Projects like Molecule by Cash App demonstrate this by using the Compose runtime to build reactive state machines without any UI components.
UI Layer
Built on top of the Runtime, the UI layer provides the core systems for rendering: layout measurement through LayoutNode, drawing with DrawScope, modifier chains, input handling, focus management, and text rendering. This layer offers the tools needed to construct custom UI components from scratch.
The Layout composable lives here, allowing you to define custom measurement and placement logic. The modifier system is also part of this layer, providing the chain of decorations (padding, sizing, drawing, input) that wrap around layout nodes. If you need a component that does not follow any existing layout pattern, the UI layer is where you build it.
Foundation Layer
The Foundation layer provides design system agnostic building blocks: Row, Column, Box, LazyColumn, LazyRow, gesture detectors, scroll behavior, and basic interactive components. It serves as the base for creating your own design system or layout structures without committing to Material Design.
If you are building a custom design system that does not follow Material Design guidelines, you can depend on the Foundation layer and skip the Material layer entirely. This gives you all the structural components while allowing complete freedom in theming, typography, and component styling. Many production apps use this approach when their brand identity requires visual language that differs significantly from Material Design.
Material Layer
The Material layer implements the Material Design system on top of Foundation. It provides theming with MaterialTheme, typography, color schemes, elevation, ripple effects, and high level components like Button, TextField, Surface, Scaffold, and TopAppBar. Both Material 2 (compose-material) and Material 3 (compose-material3) are available, with Material 3 being the recommended choice for new projects.
This interview continues for subscribers
Subscribe to Dove Letter for full access to exclusive interviews about Android and Kotlin development.
Become a Sponsor