Library / SDK
cortinico/kotlin-android-template avatar
cortinico/kotlin-android-template

kotlin-android-template ships CI, detekt and Maven publishing, and asks you to update key project details

Android + Kotlin + Github Actions + ktlint + Detekt + Gradle Kotlin DSL + buildSrc = ❤️

1,914 stars266 forksKotlinMIT

At a glance

What is it?
This GitHub template turns the Use this template button into an Android and Kotlin project with Gradle Kotlin DSL, four sample modules, detekt and ktlint, four GitHub Actions workflows and Maven Central publishing wired up. The trade is that you inherit the template’s static-analysis configuration and publishing setup.
Who is it for?
Adopt kotlin-android-template if you want a Kotlin Android project with static analysis and CI present in the first commit rather than added over a sprint, and you are willing to live with its detekt configuration and its prewired publishing workflows. Do not adopt it if your organisation centralises Gradle plugins, dependency versions or CI in a different system, since the template puts shared logic in buildSrc and dependencies in a version catalog you will have to unpick.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Kotlin, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Four modules so you can delete what you do not need

The template ships four sample modules, and knowing what each one is decides how much you delete on day one. `app` is the source for the final Android application. `library-android` is an Android library including UI. `library-kotlin` is a UI-less Kotlin library. `library-compose` is a UI library built with Jetpack Compose.

The README is slightly inconsistent here, describing the project as three sub-projects and then listing four, but the directory listing at the repository root confirms four module directories: `app/`, `library-android/`, `library-compose/` and `library-kotlin/`.

Covering all four is the point. An Android codebase that ships an app will usually also ship a UI library and a pure Kotlin module, and the module boundary is where Gradle configuration tends to go wrong. Having a working example of each pattern means you copy a module that already builds rather than inventing one.

Sample tests come with it too: Espresso, instrumentation and JUnit tests, which means the Gradle setup for connected and unit tests is already exercised rather than theoretical.

Detekt runs ktlint rules through its formatting plugin

Static analysis is configured through detekt, with the configuration stored at `config/detekt/detekt.yml`. The README notes that this file was generated with the `detektGenerateConfig` task, which matters because that task emits every rule with its default rather than only the ones you chose.

The generated configuration is the starting point for deciding which rules the project should enforce.

ktlint is not configured separately. The README says the template uses the detekt-formatting plugin, which includes the ktlint rules. So both tools are real but there is one configuration file, and formatting failures arrive through detekt rather than through a separate ktlint step.

That is a defensible consolidation. It also means you cannot relax a formatting rule in ktlint terms; you go through detekt's formatting rule set instead.

Dependencies live in a version catalog, shared logic in buildSrc

The build is Gradle Kotlin DSL with the Plugin DSL, and dependencies are centralised in the Gradle Version Catalog at `gradle/libs.versions.toml`. Version catalogs were the right call for this template: dependency upgrades become a one-line diff and Renovate, which the repository includes as `renovate.json`, can open them automatically.

Shared build logic goes into `buildSrc` as precompiled script plugins. This is a buildSrc-based template, so teams that standardise on included builds may want to adapt that part of the layout.

The supporting directories are worth knowing before you move anything. `config/` holds the detekt configuration. `gradle/` holds the version catalog and the Gradle wrapper. `build.gradle.kts` and `settings.gradle.kts` sit at the root alongside `gradle.properties`, and `.idea/` supplies initial settings when the project is opened in an IDE.

There is a TROUBLESHOOTING.md referenced for issues encountered while using the template, which is the first file to read when something does not build.

Four workflows, and one permission you must grant by hand

CI is GitHub Actions, and the README is explicit that you need no external service. There is one manual step: turn on Read and Write permissions in the Action Settings of your repository.

Four workflows come with it, and each has a distinct job.

Validate Gradle Wrapper at `.github/workflows/gradle-wrapper-validation.yml` checks that the Gradle wrapper has a valid checksum. That is a supply-chain check for the Gradle wrapper checksum.

Pre Merge Checks at `.github/workflows/pre-merge.yaml` runs the `build`, `check` and `publishToMavenLocal` tasks. The workflow also runs `publishToMavenLocal`, so publishing is checked locally as part of this workflow.

Publish Snapshot at `.github/workflows/publish-snapshot.yaml` publishes a `-SNAPSHOT` of the libraries to Sonatype, triggered manually via `workflow_dispatch` or on every merge.

Publish Release at `.github/workflows/publish-release.yaml` publishes a release version to Maven Central on tag pushes, and can also be triggered manually.

Deleting the two publishing workflows is an option for teams that do not want them; the README specifically recommends it for JitPack users.

Maven Central needs four secrets and a GPG key

Publishing is wired up rather than sketched, which is the template's most reusable contribution for anyone who has set this up before.

For each module you want to publish, you add the plugin:

code
plugins {
    publish
}

Then four repository secrets. `ORG_GRADLE_PROJECT_NEXUS_USERNAME` and `ORG_GRADLE_PROJECT_NEXUS_PASSWORD` hold the Sonatype service credentials used for Nexus and Jira. `ORG_GRADLE_PROJECT_SIGNING_KEY` holds the GPG private key, obtained with `gpg --armor --export-secret-keys <[email protected]>`, and it must start with `-----BEGIN PGP PRIVATE KEY BLOCK-----`. `ORG_GRADLE_PROJECT_SIGNING_PWD` holds the passphrase for that key.

The `ORG_GRADLE_PROJECT_` prefix is what makes these work: Gradle maps that prefix onto project properties, which is how the signing and publishing plugins pick them up without any wiring code.

One detail already handled for you: the template attaches `-sources.jar` to publications through the new AGP publishing DSL. Getting sources jars attached is a routine omission in hand-rolled setups, and having it correct from the start is worth the template on its own.

JitPack is the alternative path and needs no secrets at all; the README says to configure the repository on JitPack and delete both publishing workflows, since JitPack handles building. One caution: pgpkeygen.com is offered in the README as an online option for creating a key. For a key that will sign artifacts you publish forever, generating it offline with the `gpg` command above is the better choice.

What you inherit, and the four edits to make immediately

A template's cost is inheritance. Concretely, you inherit a detekt configuration with every rule at its default, a buildSrc layout that some organisations have moved past, four CI workflows that run on every push, two AndroidManifest files pointing at the template's package, and dependency versions chosen by someone else.

The README identifies three areas to update. Update the App ID in `buildSrc/src/main/java/Coordinates.kt`, update the two AndroidManifest files it names (`app/src/main/AndroidManifest.xml` and `library-compose/src/main/AndroidManifest.xml`), and update the package of the source files.

That last one is the tedious part and the one most likely to be left half-done. Renaming a package in Kotlin means moving directories and rewriting the package declaration in every file, and missing one leaves you with a duplicate package that compiles but belongs to someone else's coordinate.

The topics attached to the repository place this in the Hacktoberfest template category, which tells you the audience: people starting a new Android project who want working tooling immediately rather than an opinionated production setup.

On maintenance, the repository is not archived and the last push was on 2026-10-13, and it has no GitHub releases. That absence is worth noting; Renovate is included for dependency updates, while the repository has no GitHub releases. If the four workflows and the buildSrc layout both feel wrong to your team, the honest cost is forking and cutting rather than adopting and adapting.

Editorial conclusion

Adopt kotlin-android-template if you want a Kotlin Android project with static analysis and CI present in the first commit rather than added over a sprint, and you are willing to live with its detekt configuration and its prewired publishing workflows. Do not adopt it if your organisation centralises Gradle plugins, dependency versions or CI in a different system, since the template puts shared logic in buildSrc and dependencies in a version catalog you will have to unpick. Before your first commit, change the app ID in buildSrc/src/main/java/Coordinates.kt, both AndroidManifest files, and the source package, then turn on Read and Write permissions for Actions, which the README flags as the one manual step needed for CI to run.

Frequently asked questions

How do I create a project from kotlin-android-template?

The README says to click the Use this template button to create a new repository starting from the template. Once created, it says to update the App ID in buildSrc/src/main/java/Coordinates.kt, both AndroidManifest files, and the package of the source files.

Which static analysis tools does the template configure?

It uses detekt with the configuration in config/detekt/detekt.yml, a file generated by the detektGenerateConfig task, and it pulls in the ktlint rules through the detekt-formatting plugin rather than configuring ktlint separately.

Which GitHub Actions workflows does the template include?

Validate Gradle Wrapper for wrapper checksums, Pre Merge Checks running the build, check and publishToMavenLocal tasks, Publish Snapshot for -SNAPSHOT artifacts to Sonatype, and Publish Release which publishes to Maven Central on tag pushes. You must enable Read and Write permissions in the Action Settings for CI to work.

What secrets do I need to publish to Maven Central?

Four: ORG_GRADLE_PROJECT_NEXUS_USERNAME and ORG_GRADLE_PROJECT_NEXUS_PASSWORD for Sonatype, plus ORG_GRADLE_PROJECT_SIGNING_KEY holding the armored GPG private key and ORG_GRADLE_PROJECT_SIGNING_PWD holding its passphrase. The template already attaches -sources.jar through the AGP publishing DSL.

Official sources

  1. cortinico/kotlin-android-template on GitHub
  2. Issues
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/cortinico-kotlin-android-template.svg)](https://hysenlabs.com/projects/cortinico-kotlin-android-template)

Was this useful?