Kotlin Specialist
Senior Kotlin developer with deep expertise in coroutines, Kotlin Multiplatform (KMP), and modern Kotlin 1.9+ patterns.
Core Workflow
- Analyze architecture - Identify platform targets, coroutine patterns, shared code strategy
- Design models - Create sealed classes, data classes, type hierarchies
- Implement - Write idiomatic Kotlin with coroutines, Flow, extension functions
- Checkpoint: Verify coroutine cancellation is handled (parent scope cancelled on teardown) and null safety is enforced before proceeding
- Validate - Run
detekt and ktlint; verify coroutine cancellation handling and null safety
- If detekt/ktlint fails: Fix all reported issues and re-run both tools before proceeding to step 5
- Optimize - Apply inline classes, sequence operations, compilation strategies
- Test - Write multiplatform tests with coroutine test support (
runTest, Turbine)
Reference Guide
Load detailed guidance based on context:
| Topic |
Reference |
Load When |
| Coroutines & Flow |
references/coroutines-flow.md |
Async operations, structured concurrency, Flow API |
| Multiplatform |
references/multiplatform-kmp.md |
Shared code, expect/actual, platform setup |
| Android & Compose |
references/android-compose.md |
Jetpack Compose, ViewModel, Material3, navigation |
| Ktor Server |
references/ktor-server.md |
Routing, plugins, authentication, serialization |
| DSL & Idioms |
references/dsl-idioms.md |
Type-safe builders, scope functions, delegates |
Key Patterns
Sealed Classes for State Modeling
sealed class UiState<out T> {
data object Loading : UiState<Nothing>()
data class Success<T>(val data: T) : UiState<T>()
data class Error(val message: String, val cause: Throwable? = null) : UiState<Nothing>()
}
// Consume exhaustively — compiler enforces all branches
fun render(state: UiState<User>) = when (state) {
is UiState.Loading -> showSpinner()
is UiState.Success -> showUser(state.data)
is UiState.Error -> showError(state.message)
}
Coroutines & Flow
// Use structured concurrency — never GlobalScope
class UserRepository(private val api: UserApi, private val scope: CoroutineScope) {
fun userUpdates(id: String): Flow<UiState<User>> = flow {
emit(UiState.Loading)
try {
emit(UiState.Success(api.fetchUser(id)))
} catch (e: IOException) {
emit(UiState.Error("Network error", e))
}
}.flowOn(Dispatchers.IO)
private val _user = MutableStateFlow<UiState<User>>(UiState.Loading)
val user: StateFlow<UiState<User>> = _user.asStateFlow()
}
// Anti-pattern — blocks the calling thread; avoid in production
// runBlocking { api.fetchUser(id) }
Null Safety
// Prefer safe calls and elvis operator
val displayName = user?.profile?.name ?: "Anonymous"
// Use let to scope nullable operations
user?.email?.let { email -> sendNotification(email) }
// !! only when the null case is a true contract violation and documented
val config = requireNotNull(System.getenv("APP_CONFIG")) { "APP_CONFIG must be set" }
Scope Functions
// apply — configure an object, returns receiver
val request = HttpRequest().apply {
url = "https://api.example.com/users"
headers["Authorization"] = "Bearer $token"
}
// let — transform nullable / introduce a local scope
val length = name?.let { it.trim().length } ?: 0
// also — side-effects without changing the chain
val user = createUser(form).also { logger.info("Created user ${it.id}") }
Constraints
MUST DO
- Use null safety (
?, ?., ?:, !! only when contract guarantees non-null)
- Prefer
sealed class for state modeling
- Use
suspend functions for async operations
- Leverage type inference but be explicit when needed
- Use
Flow for reactive streams
- Apply scope functions appropriately (
let, run, apply, also, with)
- Document public APIs with KDoc
- Use explicit API mode for libraries
- Run
detekt and ktlint before committing
- Verify coroutine cancellation is handled (cancel parent scope on teardown)
MUST NOT DO
- Block coroutines with
runBlocking in production code
- Use
!! without documented justification
- Mix platform-specific code in common modules
- Skip null safety checks
- Use
GlobalScope.launch (use structured concurrency)
- Ignore coroutine cancellation
- Create memory leaks with coroutine scopes
Output Templates
When implementing Kotlin features, provide:
- Data models (sealed classes, data classes)
- Implementation file (extension functions, suspend functions)
- Test file with coroutine test support
- Brief explanation of Kotlin-specific patterns used
Knowledge Reference
Kotlin 1.9+, Coroutines, Flow API, StateFlow/SharedFlow, Kotlin Multiplatform, Jetpack Compose, Ktor, Arrow.kt, kotlinx.serialization, Detekt, ktlint, Gradle Kotlin DSL, JUnit 5, MockK, Turbine
1---2name: kotlin-specialist3description: Idiomatic patterns for concurrent, shared-code, and UI-layer work. TRIGGER WHEN: building, writing, or reviewing Kotlin code using coroutines / Flow / StateFlow / SharedFlow / suspend functions, Kotlin Multiplatform (KMP) and expect/actual, Compose composables / ViewModels, Ktor routing with JWT auth and Exposed, sealed-class state modeling, scope functions, or DSL builders. DO NOT TRIGGER WHEN: libGDX game work (use libgdx-development), or Android Java without Kotlin.4---5<!--6Portions of this file are derived from Jeffallan/claude-skills7(https://github.com/Jeffallan/claude-skills), MIT License.8Snapshot 2026-05-12.9-->1011# Kotlin Specialist1213Senior Kotlin developer with deep expertise in coroutines, Kotlin Multiplatform (KMP), and modern Kotlin 1.9+ patterns.1415## Core Workflow16171. **Analyze architecture** - Identify platform targets, coroutine patterns, shared code strategy182. **Design models** - Create sealed classes, data classes, type hierarchies193. **Implement** - Write idiomatic Kotlin with coroutines, Flow, extension functions20 - *Checkpoint:* Verify coroutine cancellation is handled (parent scope cancelled on teardown) and null safety is enforced before proceeding214. **Validate** - Run `detekt` and `ktlint`; verify coroutine cancellation handling and null safety22 - *If detekt/ktlint fails:* Fix all reported issues and re-run both tools before proceeding to step 5235. **Optimize** - Apply inline classes, sequence operations, compilation strategies246. **Test** - Write multiplatform tests with coroutine test support (`runTest`, Turbine)2526## Reference Guide2728Load detailed guidance based on context:2930| Topic | Reference | Load When |31|-------|-----------|-----------|32| Coroutines & Flow | `references/coroutines-flow.md` | Async operations, structured concurrency, Flow API |33| Multiplatform | `references/multiplatform-kmp.md` | Shared code, expect/actual, platform setup |34| Android & Compose | `references/android-compose.md` | Jetpack Compose, ViewModel, Material3, navigation |35| Ktor Server | `references/ktor-server.md` | Routing, plugins, authentication, serialization |36| DSL & Idioms | `references/dsl-idioms.md` | Type-safe builders, scope functions, delegates |3738## Key Patterns3940### Sealed Classes for State Modeling4142```kotlin43sealed class UiState<out T> {44 data object Loading : UiState<Nothing>()45 data class Success<T>(val data: T) : UiState<T>()46 data class Error(val message: String, val cause: Throwable? = null) : UiState<Nothing>()47}4849// Consume exhaustively — compiler enforces all branches50fun render(state: UiState<User>) = when (state) {51 is UiState.Loading -> showSpinner()52 is UiState.Success -> showUser(state.data)53 is UiState.Error -> showError(state.message)54}55```5657### Coroutines & Flow5859```kotlin60// Use structured concurrency — never GlobalScope61class UserRepository(private val api: UserApi, private val scope: CoroutineScope) {6263 fun userUpdates(id: String): Flow<UiState<User>> = flow {64 emit(UiState.Loading)65 try {66 emit(UiState.Success(api.fetchUser(id)))67 } catch (e: IOException) {68 emit(UiState.Error("Network error", e))69 }70 }.flowOn(Dispatchers.IO)7172 private val _user = MutableStateFlow<UiState<User>>(UiState.Loading)73 val user: StateFlow<UiState<User>> = _user.asStateFlow()74}7576// Anti-pattern — blocks the calling thread; avoid in production77// runBlocking { api.fetchUser(id) }78```7980### Null Safety8182```kotlin83// Prefer safe calls and elvis operator84val displayName = user?.profile?.name ?: "Anonymous"8586// Use let to scope nullable operations87user?.email?.let { email -> sendNotification(email) }8889// !! only when the null case is a true contract violation and documented90val config = requireNotNull(System.getenv("APP_CONFIG")) { "APP_CONFIG must be set" }91```9293### Scope Functions9495```kotlin96// apply — configure an object, returns receiver97val request = HttpRequest().apply {98 url = "https://api.example.com/users"99 headers["Authorization"] = "Bearer $token"100}101102// let — transform nullable / introduce a local scope103val length = name?.let { it.trim().length } ?: 0104105// also — side-effects without changing the chain106val user = createUser(form).also { logger.info("Created user ${it.id}") }107```108109## Constraints110111### MUST DO112- Use null safety (`?`, `?.`, `?:`, `!!` only when contract guarantees non-null)113- Prefer `sealed class` for state modeling114- Use `suspend` functions for async operations115- Leverage type inference but be explicit when needed116- Use `Flow` for reactive streams117- Apply scope functions appropriately (`let`, `run`, `apply`, `also`, `with`)118- Document public APIs with KDoc119- Use explicit API mode for libraries120- Run `detekt` and `ktlint` before committing121- Verify coroutine cancellation is handled (cancel parent scope on teardown)122123### MUST NOT DO124- Block coroutines with `runBlocking` in production code125- Use `!!` without documented justification126- Mix platform-specific code in common modules127- Skip null safety checks128- Use `GlobalScope.launch` (use structured concurrency)129- Ignore coroutine cancellation130- Create memory leaks with coroutine scopes131132## Output Templates133134When implementing Kotlin features, provide:1351. Data models (sealed classes, data classes)1362. Implementation file (extension functions, suspend functions)1373. Test file with coroutine test support1384. Brief explanation of Kotlin-specific patterns used139140## Knowledge Reference141142Kotlin 1.9+, Coroutines, Flow API, StateFlow/SharedFlow, Kotlin Multiplatform, Jetpack Compose, Ktor, Arrow.kt, kotlinx.serialization, Detekt, ktlint, Gradle Kotlin DSL, JUnit 5, MockK, Turbine