Oct 29, 2026

Hand Your Agent 228 Production Kotlin Traps With kotlin-footguns

Ten area skills plus a scanner, mined from a 10.8k-star Compose Multiplatform music app: 228 ways Kotlin, Compose, Room, and the desktop JVM fail in practice, each paired with a command to verify it on your own tree.

#tutorial#debugging#engineering

Most Kotlin skill collections are written from the official docs, so they tell an agent what an API is supposed to do. kotlin-footguns is a 2k-star corpus of 228 traps written from the other direction — what actually happened when its author shipped SimpMusic, a Compose Multiplatform music app, to real users for years.

Why This Skill Matters

The README's framing: every lesson here is older than the document that describes it, paid for first in crash reports, failed releases, review rounds, and user-filed issues. The source is SimpMusic, a cross-platform music client in production since April 2023 with more than 10,800 stars, shipping to Android, Windows, macOS, and Linux.

The traps are grouped into ten area skills in the open agent-skills format, plus an eleventh, footgun-scan, that checks a change against them. The corpus is deliberately service-neutral: no service names or vendor field names appear in any trap file.

Installation

Two ways in, and the README says to pick one — installing both leaves you with every skill twice. As a managed Claude Code plugin that updates with the repo:

/plugin marketplace add maxrave-dev/kotlin-footguns
/plugin install kotlin-footguns@maxrave

Updates arrive with /plugin marketplace update maxrave. Or as editable files for any agent:

npx skills@latest add maxrave-dev/kotlin-footguns

The installer lets you pick which of the eleven skills to take and which agents to install them for — Claude Code, Cursor, Codex, Copilot, Windsurf, Gemini, and others. The files land in your repository as ordinary markdown you own; pull newer versions with npx skills update.

Real Workflow: Scan a Compose Change Before Merge

The ten area skills and their trap counts, from the README:

Area skillTrapsFocus
desktop-and-build-footguns24Native code on the desktop JVM; desktop packaging, code signing, CI and build
kmp-architecture-footguns25Multiplatform module structure, dependency injection, architecture; Kotlin language traps
media-playback-footguns33Players and crossfade, audio processing and DSP, queues, shared listening sessions
data-layer-footguns26Room and SQL at scale, migrations, repositories, caching and paging
compose-visuals-footguns36Theming and colour, gradients and scrims, effects and animation, charts
compose-screens-footguns32Screens, navigation, adaptive layout, components and interaction
state-and-background-footguns23Flow, StateFlow and ViewModel lifecycles; background work, services, platform runtime
webview-footguns3WebView on low-RAM phones and provider-less devices: startup, renderer death, AndroidView lifecycle, cookies
remote-api-footguns17Clients and parsing, auth and retries, realtime sessions and wire protocols
engineering-method-footguns9Experiments, build logs, commit history, changelogs, removing a feature
  1. Work on a Compose screen as usual. When the task touches an area, the agent loads that area's index, sees every trap with the symptom that should send it there, and opens only the files that apply.
  2. Before committing, ask in plain words: "check my uncommitted Kotlin changes for footguns." footgun-scan matches 32 patterns against the lines your change adds; each pattern is tied to one trap, and the agent opens that trap to confirm or dismiss every hit.
  3. Read the verdicts. A hit is likely when the shape is wrong unless the exception its trap names holds, and look when it marks a place the trap says to inspect. The look hits are places to read, not verdicts.
  4. Wire the same scan into CI:
python3 .claude/skills/footgun-scan/scripts/scan.py --base origin/main --fail

Over the whole of SimpMusic and its core module the README reports 26 likely hits, all 26 matching their trap on inspection: 22 vertical slides left at their half-height default, two fades from Color.Transparent into a colour, and two values spliced into migration SQL.

Tips

  • Every trap file follows one discipline: frontmatter, a short orientation, a dominant Traps section, and a Verifying it section whose quantities are commands you run rather than numbers that go stale. Files stay between 60 and 140 lines.
  • The ten-skill layout exists for context budget reasons. The README explains that Claude Code lists every installed skill's name and description on every turn within a budget of 1% of the context window, and that the pre-2.0 per-trap layout blew through it; the current listing is about 2,900 characters.
  • The whole index on one page is CATALOG.md, generated by scripts/build_index.py, which fails if a file is unlisted, listed twice, or missing, or if a cross-reference names a trap that does not exist.
  • The README's evals/ holds thirteen claude plugin eval cases. With the plugin the trap questions passed in every run; without it the model averaged 0.56 and on four questions was confidently wrong — it described a Room connection-routing rule and a resource formatter that do not exist.

When Not to Use This

This corpus is Kotlin, Compose Multiplatform, and desktop JVM specific; it teaches architecture and failure modes, never the mechanics of any third-party service, so it will not explain a vendor SDK. The whole repository is GPL-3.0, matching the source project — check that before vendoring the files into a codebase with a different license. And the README itself warns that look hits are not verdicts; treat the scanner as a reading list, not a check that replaces review.


See the leaderboard for more skills.