A modern, production-ready starter template for Android apps built with Jetpack Compose. It wires together the libraries and architectural patterns most teams reach for on day one — Compose + Material 3, Hilt, Coroutines/Flow, Room, Retrofit, and type-safe Navigation — so you can delete the example screens and start building your app immediately.
- Jetpack Compose — 100% declarative UI, no XML layouts.
- Material 3 — full light/dark color schemes with dynamic color (Android 12+) support.
- Unidirectional data flow (MVI-style) — each screen exposes a single sealed
UiStateviaStateFlow, driven by sealedEvent/Intenttypes:Event -> ViewModel -> StateFlow<UiState> -> Composable. - Hilt — compile-time-safe dependency injection for ViewModels, repositories, and the database/network layer.
- Coroutines & Flow — structured concurrency throughout the data and domain layers.
- Room — local persistence with KSP-generated DAOs.
- Retrofit + OkHttp — typed REST networking with Gson conversion and HTTP logging.
- Type-safe Navigation Compose — destinations are
@SerializableKotlin types (no string routes, no manual argument parsing). - Domain layer (use cases) — ViewModels depend on small, single-purpose use cases instead of repositories directly.
- AGP 9 built-in Kotlin — no separate
org.jetbrains.kotlin.androidplugin; Compose is compiled with the dedicatedorg.jetbrains.kotlin.plugin.composeGradle plugin. - Gradle version catalog (
libs.versions.toml) as the single source of truth for every dependency and plugin version. - Gradle build/configuration cache enabled for faster local builds.
The project follows a light, pragmatic MVI-inspired unidirectional data flow on top of a
conventional presentation -> domain -> data layering:
UI (Composable)
│ dispatches Event/Intent
▼
ViewModel ──────────────► StateFlow<UiState> ──────────────► UI (Composable) re-renders
│
│ calls
▼
UseCase (domain layer)
│
▼
Repository (data layer)
│
├──► Retrofit (remote / AppApi)
└──► Room (local / ExampleDao)
- UI layer (
ui/): Composables are stateless functions of a singleUiState. They never talk to the domain/data layers directly — they only dispatchEvents to the ViewModel. - ViewModel (
ui/<feature>/<Feature>ViewModel.kt): the only place mutable state lives (MutableStateFlow). It exposes an immutableStateFlow<UiState>and a singleonEvent(event)entry point. - Domain layer (
domain/usecase/): small, single-purpose use cases (e.g.GetExamplesUseCase) that encapsulate business logic and decouple ViewModels from repositories. - Data layer (
data/):ExampleRepositoryis the single source of truth, combining the remote API (AppApivia Retrofit) and local storage (ExampleDaovia Room), and exposes results wrapped in aResource<T>(Loading/Success/Error) sealed class. - Navigation (
navigation/): destinations are@Serializabletypes (Screen.Main,Screen.Detail(id)) consumed through Navigation Compose's type-safecomposable<T>API. - Dependency injection (
di/): Hilt modules provide the Retrofit/OkHttp client, the Room database, and application-scoped coroutine scope.
app/src/main/java/com/ferhatozcelik/jetpackcomposetemplate/
├── App.kt # @HiltAndroidApp Application class
├── data/
│ ├── dao/ # Room DAOs
│ ├── entity/ # Room entities
│ ├── local/ # RoomDatabase + TypeConverters
│ ├── model/ # Network/domain models (ExampleModel, Resource<T>)
│ ├── remote/ # Retrofit service interfaces (AppApi)
│ └── repository/ # Single source of truth (ExampleRepository)
├── domain/
│ └── usecase/ # Business logic, decoupled from data sources
├── di/ # Hilt modules (network, database, app-scoped coroutine scope)
├── navigation/ # Screen.kt (type-safe routes) + NavGraph.kt
├── ui/
│ ├── activitys/ # MainActivity (single-Activity host)
│ ├── detail/ # DetailScreen + DetailViewModel + DetailUiState/Event
│ ├── home/ # MainScreen + HomeViewModel + HomeUiState/Event
│ └── theme/ # Material 3 Color/Theme/Type
└── util/ # Small extension functions and helpers
- Android Studio (a recent stable release that supports AGP 9.x / Kotlin 2.4.x)
- JDK 17
- An Android SDK with platform 36 and build-tools 36.0.0 installed
- Clone the repository
git clone https://github.com/ferhatozcelik/jetpack-compose-template.git cd jetpack-compose-template - Open in Android Studio and let it sync, or build from the command line:
./gradlew build
- Run the app
or press Run in Android Studio.
./gradlew installDebug
- Run tests
./gradlew test
The package/namespace com.ferhatozcelik.jetpackcomposetemplate is left as-is intentionally so
you can Find & Replace it project-wide with your own application ID when starting a new project.
| Component | Version |
|---|---|
| Gradle | 9.3.1 |
| Android Gradle Plugin (AGP) | 9.1.1 |
| Kotlin | 2.4.20 |
| KSP | 2.3.12 |
minSdk |
24 |
compileSdk / targetSdk |
36 |
| Jetpack Compose BOM | 2026.06.00 |
| Navigation Compose | 2.9.8 |
Hilt (hilt-android) |
2.60.1 |
androidx.hilt:hilt-navigation-compose |
1.3.0 |
| Room | 2.8.5 |
| Retrofit | 3.0.0 |
OkHttp (logging-interceptor) |
5.4.0 |
Lifecycle (lifecycle-runtime-ktx, ViewModel/Runtime Compose) |
2.10.0 |
kotlinx-serialization-json |
1.11.0 |
kotlinx-coroutines |
1.11.0 |
All versions are pinned in
gradle/libs.versions.toml— that file is the single source of truth; update it there rather than in individualbuild.gradlefiles. A few libraries are intentionally kept slightly behind their absolute latest release where a newer version raises the minimum requiredcompileSdkabove 36 (Compose BOM, Navigation Compose, Lifecycle Compose artifacts,hilt-navigation-compose, OkHttp); bumpcompileSdktogether with those dependencies if you upgrade further.
Contributions are welcome! Please read CONTRIBUTING.md for the branch/PR workflow, commit message format, and code style guidelines, and follow our Code of Conduct. See CHANGELOG.md for a history of notable changes.
This project is licensed under the Apache License 2.0 — see the LICENSE file for the full text.
If you find this template helpful, please consider giving it a ⭐️ on GitHub — it helps others discover it too.