Skip to content
Development
Skill

/kmp-architecture-footguns

Kotlin Multiplatform structure and language traps: module splits, expect/actual, Koin and ViewModel scoping, layers, version catalogs, erased overloads, Char and string-resource formatting limits. Use when shaping modules or DI, when a format specifier renders verbatim, or code

BOOST
From plugin
kotlin-footguns
1.3k10 skills
Install
$ npx -y skills add maxrave-dev/kotlin-footguns --skill kmp-architecture-footguns --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/kmp-architecture-footguns

Context preview

The summary Claude sees to decide when to auto-load this skill.

Kotlin Multiplatform structure and language traps: module splits, expect/actual, Koin and ViewModel scoping, layers, version catalogs, erased overloads, Char and string-resource formatting limits. Use when shaping modules or DI, when a format specifier renders verbatim, or code

SKILL.md

kmp-architecture-footguns.SKILL.md
name: kmp-architecture-footguns
description: "Kotlin Multiplatform structure and language traps: module splits, expect/actual, Koin and ViewModel scoping, layers, version catalogs, erased overloads, Char and string-resource formatting limits. Use when shaping modules or DI, when a format specifier renders verbatim, or code misbehaves on one platform."

Kotlin Multiplatform architecture and language footguns

25 traps mined from a production Kotlin and Compose Multiplatform app, one short file each under `references/`. Every file gives the working pattern, the **Traps** (the specific ways it fails in practice, and why), and a **Verifying it** section with commands to run against the user's own tree.

**How to use this index.** Match the code about to be written, or the symptom being chased, against the entries below: each names its topic and the symptom that should send you to it. Read every file that plausibly applies with the Read tool before proposing code or a fix; each is under 150 lines. Where a Verifying command names the source project's paths, substitute the equivalent paths in the user's tree.

**Cross-references.** A backticked trap name inside a file that is not listed here lives in a sibling area skill: glob `../*/references/<name>.md` to open it.

Module structure, dependency injection and architecture

  • [`kmp-module-split-for-packaging`](references/kmp-module-split-for-packaging.md) — Split one Kotlin Multiplatform UI module into a shared app LIBRARY plus thin per-platform launcher modules — an Android application module that only packages, and a JVM/desktop module that owns main() and hands off to a public function in the library. Reach for it when the Android Gradle Plugin refuses to let your app module also be a multiplatform target, when packaging config and shared UI are tangled in one build script, or when a resource accessor class stopped generating after a module became a library.
  • [`foss-vs-proprietary-module-pairs`](references/foss-vs-proprietary-module-pairs.md) — Ship one codebase in two forms — a full build carrying a proprietary or credentialed integration and an open build carrying a no-op stub — using twin modules with an identical public API selected by a Gradle property rather than product flavors, which do not exist for non-Android multiplatform targets. Reach for it when a tracking, casting, or paid-service dependency must be absent from an open-source build, when call sites are littered with build-flavor branches, or when the "clean" build still pulls the proprietary artifact through a transitive path.
  • [`clean-arch-kmp-readiness`](references/clean-arch-kmp-readiness.md) — Lay out a Kotlin Multiplatform app in layers that actually hold — a domain module carrying interfaces and models, repository implementations kept internal to the data module, and one module per external integration so a breaking service cannot spread — plus how to verify each boundary with a grep instead of trusting the diagram. Use when starting a multiplatform app, when splitting a monolithic module, or when platform types have started appearing in shared feature code.
  • [`no-use-case-layer-decision`](references/no-use-case-layer-decision.md) — Decide whether a mid-size app needs an interactor or use-case tier at all, how a clean boundary survives without one (repository interfaces plus pure mapping functions), how to prove an absence rather than assume it, and the specific signal that says it is finally time to add the tier back. Use when the tier feels like typing with no payoff, when reviewing an architecture that has none, or when the same orchestration has been pasted into a third view model.
  • [`hilt-to-koin-migration`](references/hilt-to-koin-migration.md) — Move dependency injection from an annotation-processed compile-time framework (Hilt/Dagger) to the multiplatform runtime container (Koin) — the mechanical mapping for providers, view models and qualifiers, what happens to assisted injection, and the two failure modes the migration introduces: a graph that no longer fails at compile time, and a module definition that blocks the thread starting the container. Use when planning the migration, when a binding resolves to nothing at runtime after it, or when app start got slower afterwards.
  • [`koin-viewmodel-scoping-traps`](references/koin-viewmodel-scoping-traps.md) — Wiring view models through a runtime dependency-injection container without losing track of their lifetime — the service-locator base class and what it costs, annotation-based definitions that compile but register nothing, which store owner each accessor addresses and why that (not the accessor's spelling) decides whether two screens share an instance, and what registering a view model as a process-wide singleton makes you responsible for. Use when a view model resolves to a fresh instance that should have been shared, when a lookup fails at runtime for a class that is clearly annotated, or when state vanishes between screens.
  • [`repository-resource-flow-pattern`](references/repository-resource-flow-pattern.md) — An envelope family for repository results — a remote wrapper, a local wrapper with a loading state, and a payload-free variant — plus the wrap-side and collect-side helpers that stop every view model from hand-writing the same branch, where the mapping from transport model to domain model belongs, and the one thing the envelope must never swallow. Use when designing repository return types, when error handling has drifted apart between screens, or when a cancelled screen reports a failure it never had.
  • [`kmp-gradle-settings-catalog`](references/kmp-gradle-settings-catalog.md) — Settings-file patterns for a many-module Kotlin Multiplatform repo — mapping deeply nested in-repo directories onto flat Gradle project paths, turning on typesafe project accessors and knowing how they mangle names, declaring repositories in the two places that need them, and pinning one transitive artifact rep
Read more
Ships withkotlin-footguns

By maxrave-dev — creator and maintainer of SimpMusic, the 10.8k-star cross-platform music app every lesson in this repository was mined from.

Get the whole plugin
Stats
1,305
Stars
6
Forks
Active
Maintenance
Python
Language
GPL-3.0
License
20d ago
Last commit
1mo ago
Created
5h ago
Added

Repo: maxrave-dev/kotlin-footguns

Other skills on kotlin-footguns.