Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Provides idiomatic Kotlin implementation patterns including coroutine concurrency, Flow stream handling, multiplatform architecture, Compose UI construction, Ktor server setup, and type-safe DSL design. Use when building Kotlin applications requiring coroutines, multiplatform development, or Android with Compose. Invoke for Flow API, KMP projects, Ktor servers, DSL design, sealed classes, suspend function, Android Kotlin, Kotlin Multiplatform.
.claude/skills/jeffallan-kotlin-specialist/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 35% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 67% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 29% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 15% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 28% | 0% |
Senior Kotlin developer with deep expertise in coroutines, Kotlin Multiplatform (KMP), and modern Kotlin 1.9+ patterns.
detekt and ktlint; verify coroutine cancellation handling and null safetyrunTest, Turbine)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 |
kotlinsealed 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) }
kotlin// 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) }
kotlin// 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" }
kotlin// 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}") }
?, ?., ?:, !! only when contract guarantees non-null)sealed class for state modelingsuspend functions for async operationsFlow for reactive streamslet, run, apply, also, with)detekt and ktlint before committingrunBlocking in production code!! without documented justificationGlobalScope.launch (use structured concurrency)When implementing Kotlin features, provide:
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
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 16,670 | 16,832 | +1% | 1 | 1 | 0% | 3,798 | 5,124 | +35% | 0 | 0 | — |
case-02 | pass→pass | 21,897 | 19,356 | -12% | 1 | 1 | 0% | 4,668 | 5,359 | +15% | 0 | 0 | — |
case-03 | pass→pass | 22,795 | 21,780 | -4% | 1 | 1 | 0% | 4,899 | 6,281 | +28% | 0 | 0 | — |
case-04 | fail→fail | 11,343 | 14,600 | +29% | 1 | 1 | 0% | 2,228 | 4,429 | +99% | 0 | 0 | — |
case-05 | pass→pass | 14,010 | 24,874 | +78% | 1 | 1 | 0% | 2,498 | 4,576 | +83% | 0 | 0 | — |
case-06 | pass→pass | 5,798 | 10,486 | +81% | 1 | 1 | 0% | 1,256 | 3,642 | +190% | 0 | 0 | — |
case-07 | fail→pass | 15,693 | 20,873 | +33% | 1 | 1 | 0% | 3,714 | 6,220 | +67% | 0 | 0 | — |
case-08 | pass→pass | 8,939 | 8,176 | -9% | 1 | 1 | 0% | 1,735 | 2,955 | +70% | 0 | 0 | — |
case-09 | pass→pass | 14,335 | 10,699 | -25% | 1 | 1 | 0% | 2,883 | 3,661 | +27% | 0 | 0 | — |
case-10 | pass→pass | 7,918 | 8,581 | +8% | 1 | 1 | 0% | 1,607 | 3,282 | +104% | 0 | 0 | — |
case-11 | fail→pass | 15,705 | 13,409 | -15% | 1 | 1 | 0% | 3,318 | 4,281 | +29% | 0 | 0 | — |
case-12 | pass→pass | 11,184 | 11,801 | +6% | 1 | 1 | 0% | 2,349 | 3,655 | +56% | 0 | 0 | — |
case-13 | pass→pass | 15,332 | 14,399 | -6% | 1 | 1 | 0% | 2,962 | 4,432 | +50% | 0 | 0 | — |
case-14 | pass→pass | 11,109 | 13,657 | +23% | 1 | 1 | 0% | 2,594 | 4,462 | +72% | 0 | 0 | — |
case-15 | pass→pass | 14,469 | 20,062 | +39% | 1 | 1 | 0% | 3,125 | 5,187 | +66% | 0 | 0 | — |
case-16 | pass→pass | 9,125 | 9,971 | +9% | 1 | 1 | 0% | 1,773 | 3,383 | +91% | 0 | 0 | — |
case-17 | pass→pass | 13,485 | 16,966 | +26% | 1 | 1 | 0% | 2,715 | 4,818 | +77% | 0 | 0 | — |
case-18 | pass→pass | 8,674 | 13,993 | +61% | 1 | 1 | 0% | 1,741 | 4,470 | +157% | 0 | 0 | — |
case-19 | pass→pass | 9,319 | 12,778 | +37% | 1 | 1 | 0% | 1,691 | 3,961 | +134% | 0 | 0 | — |
case-20 | pass→pass | 10,847 | 16,194 | +49% | 1 | 1 | 0% | 2,491 | 4,763 | +91% | 0 | 0 | — |
case-21 | pass→pass | 13,830 | 14,532 | +5% | 1 | 1 | 0% | 3,014 | 4,538 | +51% | 0 | 0 | — |
case-22 | pass→pass | 11,471 | 13,242 | +15% | 1 | 1 | 0% | 2,589 | 4,048 | +56% | 0 | 0 | — |
case-23 | pass→pass | 8,472 | 8,953 | +6% | 1 | 1 | 0% | 1,832 | 3,122 | +70% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +13 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.