# Gemini CLI Kotlin and Android: practical agent guide

URL: https://agentvera.dev/en/blog/gemini-cli-for-kotlin/ · Published: 2026-11-01

Learn how to use Gemini CLI in Kotlin and Android projects: GEMINI.md setup, working loops, Compose and coroutine tasks, testing, and pitfalls.

**In short:**

- Gemini CLI works best in Kotlin and Android when you codify build, test, lint, and rules in GEMINI.md and keep changes small.
- Use the agent to scaffold Compose screens, refactor coroutines, and generate JUnit and Espresso tests, but review Gradle and version catalog changes closely.
- Verify every agent change with unit tests, lint, and targeted instrumented tests, and isolate parallel agents with git worktrees.

[Gemini CLI](/en/agents/gemini-cli/) is a terminal coding agent that becomes genuinely useful for Kotlin and Android when you run `gemini` in the project root and keep a tight `GEMINI.md`. It reads Gradle files, Kotlin sources, Compose composables, and test directories, then edits and runs commands against the same project state. The highest-value workflow is small, verifiable changes with the agent driving Gradle test and lint tasks after every edit.

## What Gemini CLI does well in Kotlin and Android projects

Kotlin and Android work is full of repeatable, well-structured edits: adding a composable, updating a ViewModel, changing a data class, or writing test cases. Gemini CLI suits these tasks because it can parse `build.gradle.kts`, `libs.versions.toml`, Android manifest changes, and Kotlin source sets in context. It can follow idiomatic Kotlin conventions such as sealed interfaces for UI state, data classes for models, extension functions for mapping, and coroutine flows for async work. In practice, a single request like 'add a detail screen with a ViewModel and repository flow' can produce cohesive changes across Kotlin, Compose, and test files. Gemini CLI can follow multiple files at once and keeps a mental model of the current build configuration. For example, it can add a new destination in a Compose navigation graph, create the screen, update the ViewModel, and add the unit test in one turn. That reduces the ceremony around Android boilerplate while leaving the architecture decisions to the developer. The value is not fully autonomous coding; it is using the agent as a fast, reviewable contributor that already understands Gradle output and Kotlin error messages.

## How to set up GEMINI.md for Android builds

Start by placing a `GEMINI.md` in the project root. This file is the agent’s operating manual; it should list the exact Gradle commands for build, unit test, lint, and instrumented tests, plus the package structure and rules. The more specific it is, the fewer wrong moves the agent makes. Include the module layout, Kotlin source directory (`app/src/main/kotlin`), test directory, and any version catalog rules. A short but realistic `GEMINI.md` for a single-module Compose app looks like this:

```markdown
# GEMINI.md

Project: Kotlin/Android app. Single module `app`. minSdk 26, targetSdk 35.

Build and verify:
- `./gradlew assembleDebug`
- `./gradlew testDebugUnitTest`
- `./gradlew lintDebug`
- `./gradlew connectedDebugAndroidTest` (requires emulator or device)

Folder conventions:
- UI composables: `app/src/main/kotlin/com/example/app/ui/`
- ViewModels: `app/src/main/kotlin/com/example/app/ui/<feature>/`
- Repository/data: `app/src/main/kotlin/com/example/app/data/`
- Unit tests: `app/src/test/kotlin/`
- Instrumented tests: `app/src/androidTest/kotlin/`

Rules:
- Use Kotlin idiomatic code, Jetpack Compose for new UI, and coroutines with `viewModelScope`.
- Do not edit `build/`, `.gradle/`, generated `R` files, or `libs.versions.toml` unless asked.
- Preserve state hoisting and use `collectAsStateWithLifecycle`.
- After changes, run the relevant unit tests and `./gradlew lintDebug`.
- Explain dependency or version changes before editing Gradle files.
```

Keep this file current. If you add a module or change the test command, update `GEMINI.md`; the agent reads it on every session. The file should avoid vague guidance like 'write good code'. Instead, name the module, package, and commands. If you use detekt or ktlint, add those commands too. The agent will quote the file when it is unsure, so the more accurate the instructions, the cleaner the diff. For a full walkthrough of the working style, see [How to use Gemini CLI](/en/blog/how-to-use-gemini-cli/).

## The edit-run-review loop in Android projects

Use a plan, small steps, run the tests, review the diff cycle. Start by asking Gemini CLI to inspect the relevant files and propose a plan instead of writing code immediately. Then have it implement one small slice, run `./gradlew testDebugUnitTest` and `./gradlew lintDebug`, and show the resulting `git diff`. Review the diff before continuing; if an issue appears, ask for a focused fix rather than a broad rewrite. This keeps Gradle syncs, Compose previews, and coroutine changes reviewable.

Typical prompts that work well for Kotlin and Android tasks:

- In this Android app, add a ViewModel for the search screen that exposes `StateFlow<SearchUiState>` and collects repository results with `flatMapLatest`. Keep the screen state immutable and show a loading indicator.
- Refactor the `TaskRepository` to use `Flow` instead of callbacks. Update `TaskViewModel` and unit tests; do not change UI strings or navigation graph.
- Write JUnit tests for `LoginViewModel` using `kotlinx-coroutines-test` and a fake `AuthRepository`. Cover loading, success, and error states.
- Add a Compose preview for `ProfileScreen` with sample data in the `ui/profile` package and run `./gradlew compileDebugKotlin`.
- Fix the lint warning `CoroutineCreationDuringComposition` in `HomeScreen` by launching the effect in `LaunchedEffect` rather than `rememberCoroutineScope`.

These prompts are specific enough to keep the agent on Kotlin and Android rails and produce a small diff. After each slice, ask for a one-line summary of what changed and which Gradle tasks were run. That makes the review faster and keeps the agent honest about its own verification.

## What the agent does well and common Kotlin and Android pitfalls

Gemini CLI handles structured Kotlin edits well: adding data classes, sealed UI state, mapping functions, Compose components, and unit tests. It is also good at reading Gradle task failures and proposing Kotlin fixes. It is less reliable when it changes build configuration, bumps dependency versions, or assumes an emulator is available.

| Area | What to ask for | What to review carefully |
|---|---|---|
| Build files | Add the Compose compiler plugin in the version catalog and keep Kotlin aligned. | AGP, Kotlin, Compose compiler compatibility; configuration avoidance. |
| Compose UI | Create a reusable `ListItem` composable with state hoisting and a preview. | Experimental Material3 APIs, re-composition scope, `remember` keys, `derivedStateOf`. |
| Coroutines | Replace fire-and-forget calls with `viewModelScope.launch` and expose `StateFlow`. | Scope cancellation, `GlobalScope`, `collectAsState` vs `collectAsStateWithLifecycle`. |
| Gradle tasks | Run `./gradlew testDebugUnitTest` and summarize failures. | Task selection by variant, unit vs instrumented tests, module paths. |
| Tests | Write JUnit tests for the mapper and add edge cases for null input. | Test dispatcher rules, fake data, flaky timing, Robolectric vs Espresso split. |

- Watch Gradle changes: version catalog modifications, AGP/Kotlin/Compose compiler compatibility. Require explicit approval before editing `libs.versions.toml` or plugin blocks.
- Compose pitfalls: the agent may add experimental Material3 APIs without opt-in, forget `collectAsStateWithLifecycle`, or create recomposition bugs by capturing the wrong scope.
- Coroutine pitfalls: it may use `GlobalScope` or launch in `init`; correct it to `viewModelScope` and `stateIn`.
- Source paths: Android projects often use `src/main/kotlin`, but the agent may default to `src/main/java`; verify paths before it writes.
- Instrumented tests need a device or emulator. Ask it to write Espresso tests but do not expect `connectedDebugAndroidTest` to pass without one. A common failure mode is the agent editing generated build files or trying to run instrumented tests on a machine without an emulator. Spell out in `GEMINI.md` whether the emulator is available and which test tasks are safe.

## Running JUnit, lint, and Espresso with Gemini CLI

After each agent change, run `./gradlew testDebugUnitTest` and `./gradlew lintDebug` from the terminal or let the agent run them and report. For unit tests, use JUnit with `kotlinx-coroutines-test` and Turbine for flow assertions; ask the agent to include `runTest`, `StandardTestDispatcher`, and fake repositories. For Compose UI behavior, generate Espresso tests with `createAndroidComposeRule` and have the agent add them to `app/src/androidTest/kotlin`, then run `./gradlew connectedDebugAndroidTest` on an emulator. Have the agent read failure reports such as `app/build/reports/tests/testDebugUnitTest/index.html` and lint reports under `app/build/reports/`, then propose targeted fixes. Review `git diff -- app/src/main/kotlin app/src/test app/src/androidTest` before accepting changes. Use a separate worktree or branch when asking for larger refactors so you can throw away a bad attempt without losing the current state. For small fixes, run the tests yourself before asking the agent to continue.

## Parallel agents with AgentVera on Android projects

When you need parallel work on a multi-module Android app, AgentVera runs real CLI agents such as Gemini CLI side by side, each in its own git worktree, so one agent editing `app` never overwrites another editing `core`. Automatic code review after each turn flags Kotlin or Compose issues at file:line before they land. Checkpoints let you undo a bad refactor of a ViewModel or Gradle file in one click, and token budgets stop an agent from looping on Gradle sync or lint fixes while keeping the conversation for follow-up. For orchestration patterns that fit Kotlin and Android teams, see [AI coding agent orchestration](/en/blog/ai-coding-agent-orchestration/).

## Final notes for Gemini CLI on Kotlin and Android

Gemini CLI is most productive in Kotlin and Android when you treat it as a focused pair programmer: explicit `GEMINI.md`, small changes, Gradle-backed verification. For parallel work on multi-module apps, isolate agents and add review checkpoints rather than letting them share a single working tree. Keep the loop tight and the diff small. For more on that partnership, see [AI pair programming](/en/blog/ai-pair-programming/).

## Frequently asked questions

**Can Gemini CLI edit Kotlin and Android projects?** Yes. Run gemini in the project root and provide a GEMINI.md with the Gradle commands and source paths. It can edit Kotlin, Compose, ViewModel, and test files, then run build and test commands.

**How do I configure Gemini CLI for an Android project?** Create a GEMINI.md file with build commands such as ./gradlew assembleDebug and ./gradlew testDebugUnitTest, the module layout, Kotlin source directories, and rules about Gradle changes. Keep generated files and version catalogs off-limits unless explicitly requested.

**Does Gemini CLI work with Gradle and Jetpack Compose?** Gemini CLI reads build.gradle.kts and libs.versions.toml, and it can modify Compose files, ViewModels, and tests. It still needs explicit guardrails because Gradle, Kotlin, and Compose compiler versions are tightly coupled.

**Can Gemini CLI run JUnit and Espresso tests?** It can run unit tests such as ./gradlew testDebugUnitTest and can generate JUnit and Espresso test code. For instrumented tests like connectedDebugAndroidTest, an emulator or device must be available, and you should verify the reports.

---

**About AgentVera.** AgentVera is a desktop app for macOS, Windows and Linux, built by Solviera Teknoloji. It runs 18 AI coding agents (Claude Code, Codex, Gemini CLI, Copilot, Cursor, Antigravity, opencode, Hermes, Qwen Code, Kimi Code, Kiro, Amp, Droid, Goose, Vibe, Crush, Aider, Cline) side by side, per project, in real terminals with the user's own CLI installs and logins. The free plan has unlimited agents. Download: https://agentvera.dev/en/download/ · Pricing: https://agentvera.dev/en/pricing/
