A modern, production-ready Android template built with Jetpack Compose, Navigation 3, and Kotlin. This template provides a solid foundation for building Android applications with best practices, comprehensive testing, and CI/CD already configured.
-
Click the Use this template button.
-
Clone your new repository.
-
Run the project setup wizard. It configures code-package and Gradle-project identity separately from the application ID and launcher name. It also covers app versioning, Android SDK levels, curated dependency capabilities, example-module removal, optional AI-free output, and validation. The browser downloads a configured ZIP by default:
# Browser UI: preview, then download the configured project ZIP ./scripts/setup-project.sh --ui # Repeatable CLI archive preview ./scripts/setup-project.sh \ --package com.example.myapp \ --name "My Awesome App" \ --preset standard \ --remove-examples \ --ai-free \ --archive ../my-awesome-app.zip # Create the reviewed archive ./scripts/setup-project.sh \ --package com.example.myapp \ --name "My Awesome App" \ --preset standard \ --remove-examples \ --ai-free \ --archive ../my-awesome-app.zip \ --apply
Running
./scripts/setup-project.shwithout arguments opens an interactive terminal wizard.make setupandmake setup-uiare shortcuts for the terminal and browser entry points. Both interfaces import and export the same versioned JSON configuration. The CLI also supports--outputfor a directory copy and--in-placewhen the current clone should be transformed. Seedocs/project-setup-wizard.mdfor presets, capabilities, JSON schema, configuration coverage, ZIP downloads, deployment, safety behavior, and automation examples. The wizard intentionally leaves dependency versions, build types, Gradle tuning, signing credentials, and brand assets under the template's existing manual workflows.The focused legacy rename command and its Gradle adapter remain available:
./scripts/rename-template.sh \ --package com.example.myapp \ --name "My Awesome App" \ --author "Your Name" \ --dry-run ./gradlew renameProject \ -Ppackage=com.example.myapp \ -Pname="My Awesome App" \ -Pauthor="Your Name" \ -PdryRun=true # drop this to applyThe setup wizard can run formatting and narrow or full verification as explicit final-step choices. The legacy rename command still leaves formatting as a separate step because the Gradle adapter cannot safely start a nested Gradle build. After applying, confirm the rename is complete with
./scripts/validate-rename.sh(ormake rename-validate). It fails if any original template identity, package folder, or plugin accessor remains. Then run./gradlew spotlessApplyandmake verify. Formatting is a separate step because package changes can alter Kotlin import ordering and the GradlerenameProjecttask cannot safely start a nested Gradle build. -
Update SDK and library versions in
gradle/libs.versions.tomlas needed (single source of truth for dependencies and plugin versions).
# Build the project
./gradlew assembleDebug
# Run unit tests
./gradlew test
# Run the same host-side verification used by pull requests
make verify
# Scan tracked files for credentials and sensitive release files
make secrets-check
# Run linting and static analysis
./gradlew detekt
# Run only Compose-specific static analysis
./gradlew detektCompose
# Apply fixes exposed as safe Detekt auto-corrections
./gradlew detektAutoCorrect
# Check translation completeness and formatter compatibility
make localization-check
# Format code
./gradlew spotlessApplyRelease builds use an untracked key.properties file locally and protected environment secrets in
GitHub Actions. See RELEASING.md for the copy-ready local file, GitHub secret
commands, interactive upload-key generator, protected-environment setup, and release workflow.
Enable the repository-owned pre-commit hook once per clone:
git config core.hooksPath .agents/hooksThe hook checks staged Git blobs without reading ignored local credentials. A lightweight, read-only GitHub Actions workflow repeats the check for every pull request, including documentation-only changes. After its first run, make Reject committed secrets a required status check in the default branch ruleset.
Repository administrators should also enable GitHub Secret Protection and push protection under Settings β Security β Advanced Security when available; native provider-aware scanning complements the repository's intentionally small, high-confidence rule set.
If a real credential is ever committed, revoke or rotate it immediately. Removing it in a later commit does not make the exposed value safe.
The project follows a modular layout backed by Gradle convention plugins:
See ARCHITECTURE.md for layer responsibilities, dependency direction, UI-state
rules, and the complete posts demo walkthrough.
βββ .agents/ # Shared coding-agent references, skills, and hooks
βββ AGENTS.md # Canonical coding-agent instructions
βββ app/ # Main Android application (Compose + Navigation 3)
βββ core/ # Shared production foundations and test utilities
β βββ designsystem/ # Reusable theme and Compose components
β βββ navigation/ # Navigation keys and routing contracts
β βββ database/ # Room database and schemas
β βββ testing/ # Shared test utilities and fakes
βββ feature/ # Feature-focused modules
β βββ home/ # Single-module UI feature
β βββ posts/ # Clean Architecture demo
β βββ domain/ # model/, repository/, result/, usecase/
β βββ data/ # di/, local/, remote/, mapper/, repository/
β βββ presentation/ # di/, ui/, ui/model/, ui/components/
βββ library-android/ # Android-specific library module
βββ library-kotlin/ # Pure Kotlin library module (business logic)
βββ benchmarks/ # Macrobenchmark + baseline profile generator
βββ tests/e2e/ # Managed-device application journeys
βββ build-logic/ # Shared Gradle convention plugins (includeBuild)
βββ gradle/ # Version catalog (libs.versions.toml)
βββ config/ # Detekt / KtLint / static-analysis configs
βββ spotless/ # Spotless copyright header template
βββ docs/ # Long-form guides (project setup wizard)
βββ tools/ # Dev-only tooling (localization web wizard)
βββ scripts/ # Setup wizard, rename, module, localization, and verification tooling
Convention plugins under build-logic/convention (e.g. androidlab.android.application.compose, androidlab.android.library.compose, androidlab.android.feature, androidlab.android.junit5, androidlab.android.compose.screenshot, androidlab.android.benchmark, androidlab.android.application.baselineprofile, androidlab.android.application.jacoco, androidlab.hilt, androidlab.android.room, androidlab.android.lint, androidlab.spotless, androidlab.jvm.library, and the selective androidlab.kotlin.explicit-visibility) keep per-module build.gradle.kts files small and consistent.
Kotlin packages mirror these directories. Single-module UI features use ui, ui/model, and
ui/components; reusable components shared by unrelated features live in core/designsystem.
Use scripts/add-module.sh to create and register feature, core, Android library, or Kotlin/JVM
modules. Generated Android modules intentionally start without explicit library dependencies. Add
only dependencies required by the implementation, prefer implementation, and use api only when
a dependency type is intentionally part of the module's public contract.
Library, Android build-plugin, and Android SDK versions are defined in
gradle/libs.versions.toml. The catalog is the source of truth for
those values; the summary below intentionally avoids copying fast-changing version numbers.
- Kotlin β configured through the version catalog and shared toolchains.
- Android Gradle Plugin β Android build configuration.
- Jetpack Compose β Compose BOM, Material 3, and Material 3 Adaptive.
- Navigation 3 alongside
androidx.navigation:navigation-compose. - Kotlin Coroutines and kotlinx.serialization.
- Hilt β dependency injection (+
hilt-navigation-compose). - Room β local persistence (via KSP).
- Retrofit + OkHttp β type-safe networking with a
kotlinx-serializationconverter. - Sandwich β Retrofit response wrapping.
- Paging 3 β smooth list loading.
- Coil β image loading optimized for Compose.
- kotlinx-datetime and kotlinx.collections.immutable.
- Clean Architecture + MVVM β an end-to-end paginated posts feature with enforced domain, data, and presentation module boundaries.
- JUnit 5 β modern unit testing.
- Compose Preview Screenshot Testing β host-side adaptive visual regression testing.
- Compose Guard β Compose compiler stability metrics.
- JaCoCo β coverage reports and JVM business-logic thresholds.
- Detekt + Compose Rules + KtLint + Spotless β Kotlin and Compose-specific static analysis, selective explicit-visibility enforcement for feature/layer modules, and formatting.
- Dependency Guard β transitive dependency change detection.
- MockK + Mockito + Turbine + Truth + AssertJ β testing toolkit.
- Robolectric, Compose Test, AndroidX Test, and UI Automator β local UI, integration, and end-to-end testing.
- Posts architecture demo β Retrofit pagination, in-memory cache fallback, DTO/domain/UI mapping, Hilt, sealed UI state, retry, and incremental loading.
- Adaptive Layouts β foldables and tablets via Material 3 Adaptive.
- Edge-to-Edge β modern UI implementation by default.
- Baseline Profiles β generated via
:benchmarksfor faster startup and smoother frames. - Screenshot Testing β automated adaptive UI regression with the Compose screenshot plugin.
- Dependency Guard β locks transitive dependency surface across builds.
- Opt-in Firebase and Play Publisher β catalog entries and
app/build.gradle.ktsplugin and dependency lines are present but commented out; uncomment them once the project has its owngoogle-services.jsonand Play service account. - Signing-ready β local builds resolve keystore credentials from an untracked
key.propertiesfile, while CI reads env vars (SIGNING_STORE_PASSWORD,SIGNING_KEY_ALIAS,SIGNING_KEY_PASSWORD,SIGNING_KEYSTORE_PATH); a manually approved GitHub Actions workflow restores an upload key only on its ephemeral runner and retains the signed AAB plus R8 mapping. - Localization-ready β English fallback resources, European Portuguese translations, generated per-app language configuration, pseudolocales, translation validation, a self-contained HTML status dashboard published as a CI artifact, and a dev-only web wizard for inline editing.
See LOCALIZATION.md for the resource strategy, translator workflow, status
dashboard, web wizard, and validation matrix.
# Run unit tests (JUnit 5)
./gradlew test
# Run deterministic JVM integration tests
./gradlew integrationTest
# Compose Preview screenshot tests
./gradlew validateDebugScreenshotTest # compare against approved references
./gradlew updateDebugScreenshotTest # intentionally update references
# Coverage reports and JVM business-logic gate
./gradlew coverageReport
./gradlew coverageVerification
# Instrumentation and end-to-end tests on the managed CI phone/tablet group
./gradlew ciManagedDeviceTest
# Macrobenchmarks & baseline profile
# Run timing measurements on a stable, connected physical device.
./gradlew :benchmarks:connectedBenchmarkReleaseAndroidTest
# Generate profiles reproducibly with the managed device declared by :benchmarks.
./gradlew :app:generateBaselineProfileThe Makefile wraps common Gradle invocations:
make/make helpβ list available targets without changing the project.make setup/make setup-uiβ launch the terminal or browser project setup wizard.make docs-checkβ validate documentation links and project facts.make localization-checkβ validate translated resources in every Android module.make localization-report LOCALE=pt-PT FORMAT=csvβ export translation coverage.make localization-report-htmlβ write the self-contained localization status dashboard.make localization-serve/make localization-web-buildβ run or build the dev-only localization web wizard.make secrets-checkβ reject tracked credentials and sensitive release files.make build/make installβ assemble or install the debug app.make generate-release-key/make releaseβ create an upload keystore or build the signed AAB.make testβ run unit tests.make integration-testβ run JVM integration tests.make checkβ run the routine static checks: localization, secrets, lint, Detekt, Spotless, and Dependency Guard.make verifyβ run the canonical non-mutating host checks used by pull requests.make lint/make detekt/make detekt-compose/make detekt-fixβ run Android lint, Detekt, the Compose-specific rules, or safe Detekt auto-corrections.make template-checkβ validate the rename dry run and generated module structure.make rename-validateβ verify this project was fully renamed away from the template.make format-check/make formatβ check or apply formatting.make device-testβ run debug instrumentation tests on connected devices.make device-test-ci/make device-test-allβ run every instrumentation and end-to-end test on the CI or complete managed-device matrix.make screenshot-test/make screenshot-recordβ verify or update Compose screenshot baselines.make coverage/make coverage-verifyβ generate coverage reports or enforce JVM thresholds.make dependency-guard/make dependency-guard-baselineβ verify or update dependency baselines.make benchmarkβ runbenchmarkReleasemacrobenchmarks.make baseline-profileβ generate the app baseline profile.make tasks/make gradle-versionβ list Gradle tasks or print Gradle, Kotlin, and JVM versions.
Pass additional Gradle options with GRADLE_ARGS, for example:
make verify GRADLE_ARGS="--no-daemon --stacktrace"- Android Studio β a release compatible with the AGP and SDK levels configured in
gradle/libs.versions.toml. - JDK 21 β required for the build system (set as Kotlin/Java toolchain).
- Android SDK β install the compile SDK declared in the version catalog.
- Gradle β use the checked-in wrapper (
./gradlew). - Make β required to run the project's convenience commands (e.g.,
make verify,make build).
Coding agents should start with AGENTS.md. The .agents workspace
contains progressively loaded architecture, decision, testing, security, performance, and validation
references, concrete Android/Kotlin implementation rules, reusable task skills, and an optional
pre-commit hook. CLAUDE.md remains a thin Claude Code adapter so repository guidance has one
canonical source. Complete features follow the
deliver-android-feature workflow so acceptance
criteria, implementation, every required test layer, and CI evidence remain traceable.
- Fork the repository.
- Create a feature branch.
- Ensure all CI checks pass.
- Submit a pull request.
This project is licensed under the Apache License 2.0 β see the LICENSE file for details.