# A Kotlin Production Checklist — Kotlin

Source: https://www.skillbyai.com/en/kotlin/e-checklist

> Review before shipping.

## Questions to ask

Are nullable types explicit at boundaries, with few or no `!!`? Are values `val` and collections read-only where possible? Are states and results modelled with sealed types and exhaustive `when` without `else`? Are coroutines launched in lifecycle-bound scopes, with no `GlobalScope`, blocking work on `Dispatchers.IO` and `CancellationException` never swallowed? Are Java boundaries typed explicitly and annotated for Java callers? Are tests written with kotlin.test or JUnit 5, using `runTest` for coroutines? Do ktlint and detekt run in CI, and are Kotlin and library versions kept current?

## The checklist

Use it in code review.

```bash
# [ ] prefer val and read-only List/Set/Map; data classes for values
# [ ] nullability explicit at boundaries; avoid !!; requireNotNull with messages
# [ ] sealed types + exhaustive when (no else) for states and results
# [ ] coroutines in structured scopes; no GlobalScope; runBlocking only at the edges
# [ ] Dispatchers.IO for blocking calls; rethrow CancellationException
# [ ] platform types pinned; @JvmStatic / @JvmOverloads for Java callers
# [ ] tests with kotlin.test / JUnit 5, MockK, runTest
# [ ] style and static analysis in CI
./gradlew ktlintCheck detekt test     # task names depend on the plugins you apply
```

## Let the compiler work for you

Turn on `allWarningsAsErrors` in CI once warnings are under control; Kotlin warnings often point at real nullability or deprecation problems.

**Quiz:** Which practice belongs on a Kotlin production checklist?

- [ ] Add else to every when over a sealed type
- [ ] Use !! wherever the compiler complains
- [x] Launch coroutines in lifecycle-bound scopes instead of GlobalScope
- [ ] Call runBlocking inside suspend functions

*Answer:* Launch coroutines in lifecycle-bound scopes instead of GlobalScope. Structured scopes prevent leaked work.
