Android Development
dpconde/claude-android-skill
Create production-quality Android applications following Google's official architecture guidance and NowInAndroid best practices.
Load, when a developer writes, reviews, or debugs Kotlin coroutine code and needs help spotting concurrency bugs — GlobalScope leaks, runBlocking in suspend, missing Flow catch, hardcoded or wrong…
$ npx skills add santimattius/structured-coroutines --skill kotlin-coroutines-skill -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install santimattius/structured-coroutines kotlin-coroutines-skill --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/santimattius/structured-coroutines.git skills-src && mkdir -p .claude/skills && cp -r skills-src/kotlin-coroutines-skill .claude/skills/kotlin-coroutines-skill && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "kotlin-coroutines-skill" agent skill from https://github.com/santimattius/structured-coroutines/tree/main/kotlin-coroutines-skill into .claude/skills/kotlin-coroutines-skill/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kotlin-coroutines-skill", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/santimattius/structured-coroutines/tree/main/kotlin-coroutines-skillType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add santimattius/structured-coroutines --skill kotlin-coroutines-skill -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install santimattius/structured-coroutines kotlin-coroutines-skill --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/santimattius/structured-coroutines.git skills-src && mkdir -p .agents/skills && cp -r skills-src/kotlin-coroutines-skill .agents/skills/kotlin-coroutines-skill && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "kotlin-coroutines-skill" agent skill from https://github.com/santimattius/structured-coroutines/tree/main/kotlin-coroutines-skill into .agents/skills/kotlin-coroutines-skill/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kotlin-coroutines-skill", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add santimattius/structured-coroutines --skill kotlin-coroutines-skill -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install santimattius/structured-coroutines kotlin-coroutines-skill --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/santimattius/structured-coroutines.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/kotlin-coroutines-skill .cursor/skills/kotlin-coroutines-skill && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "kotlin-coroutines-skill" agent skill from https://github.com/santimattius/structured-coroutines/tree/main/kotlin-coroutines-skill into .cursor/skills/kotlin-coroutines-skill/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kotlin-coroutines-skill", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/santimattius/structured-coroutines.git --path kotlin-coroutines-skill--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add santimattius/structured-coroutines --skill kotlin-coroutines-skill -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install santimattius/structured-coroutines kotlin-coroutines-skill --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/santimattius/structured-coroutines.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/kotlin-coroutines-skill .gemini/skills/kotlin-coroutines-skill && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "kotlin-coroutines-skill" agent skill from https://github.com/santimattius/structured-coroutines/tree/main/kotlin-coroutines-skill into .gemini/skills/kotlin-coroutines-skill/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kotlin-coroutines-skill", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install santimattius/structured-coroutines kotlin-coroutines-skillInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add santimattius/structured-coroutines --skill kotlin-coroutines-skill -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/santimattius/structured-coroutines.git skills-src && mkdir -p .github/skills && cp -r skills-src/kotlin-coroutines-skill .github/skills/kotlin-coroutines-skill && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "kotlin-coroutines-skill" agent skill from https://github.com/santimattius/structured-coroutines/tree/main/kotlin-coroutines-skill into .github/skills/kotlin-coroutines-skill/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kotlin-coroutines-skill", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add santimattius/structured-coroutines --skill kotlin-coroutines-skill -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install santimattius/structured-coroutines kotlin-coroutines-skill --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/santimattius/structured-coroutines.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/kotlin-coroutines-skill .opencode/skills/kotlin-coroutines-skill && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "kotlin-coroutines-skill" agent skill from https://github.com/santimattius/structured-coroutines/tree/main/kotlin-coroutines-skill into .opencode/skills/kotlin-coroutines-skill/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "kotlin-coroutines-skill", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
kotlin-coroutines-skillLoad, when a developer writes, reviews, or debugs Kotlin coroutine code and needs help spotting concurrency bugs — GlobalScope leaks, runBlocking in suspend, missing Flow catch, hardcoded or wrong…
Kotlin Coroutines Skill is an agent skill from santimattius/structured-coroutines. Load, when a developer writes, reviews, or debugs Kotlin coroutine code and needs help spotting concurrency bugs — GlobalScope leaks, runBlocking in suspend, missing Flow catch, hardcoded or wrong dispatchers, unhandled timeouts, cancellation and structured-concurrency mistakes — or asks how to make async Kotlin testable.
Its SKILL.md is about 6.8k tokens, which your agent loads only when the skill is triggered. The skill folder holds 60 other files, including reference files (for example `references/ref-1-1-global-scope.md`, `references/ref-1-2-async-without-await.md` and `references/ref-1-3-breaking-structured-concurrency.md`).
It sits in Mobile, covering Android development. It works with Kotlin, Android and Gradle. The repository describes itself as: The definitive toolkit for enforcing safety, predictability, and efficiency in Kotlin Coroutines. The licence is Apache-2.0.
12 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 1037e0c. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are kotlin).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Kotlin Coroutines Skill loads about 6.8k tokens when it runs, and up to ~29k if it reads all its reference files. Until then it costs about 87 tokens; SKILL.md has 1,732 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from santimattius/structured-coroutines at commit 1037e0c, republished under its Apache-2.0 licence (© santimattius). 1,732 words, ~6,830 tokens.
.claude/skills/kotlin-coroutines-skill/SKILL.md (or your agent's skills folder). This skill also uses 59 other files; get the full folder from GitHub.This skill provides expert guidance on Kotlin Coroutines, covering structured concurrency, scopes,
Dispatchers (including main-safe suspend and dispatcher injection), cancellation (including
withTimeout semantics), exception handling (CoroutineExceptionHandler, launch vs async),
Channels, Flow (cold vs hot, collectLatest, SharedFlow configuration, blocking in flow {}),
lifecycle-aware collection on Android, and testing (virtual time, setMain/resetMain). Use this
skill to help developers write safe, maintainable concurrent code aligned with Kotlin 1.9+/2.0+
conventions and official best practices.
references/.GlobalScope in production. Use framework scopes (viewModelScope,
lifecycleScope, rememberCoroutineScope), injected scopes, or local scopes (
coroutineScope { }, withContext { }). If an external scope is required, justify and document
it.async only when a return value is needed; if await() is never called, use launch.
Preserve structured concurrency: inside suspend functions use coroutineScope { } + async/
launch; do not launch in an external scope from suspend unless work must outlive the flow, and
then document it.runBlocking inside suspend functions or coroutine-based code. Avoid ending a suspend
function with coroutineScope { launch { } } as the last line when the intent is fire-and-forget
— coroutineScope waits for all children and blocks the caller; use an explicit external scope
and document it if the work must truly run in the background beyond the caller's lifetime.Dispatchers.Default for CPU-bound work, Dispatchers.Main/
Main.immediate for UI, withContext(Dispatchers.IO) for blocking I/O. Never perform blocking
I/O on Default or Main. Do not use Dispatchers.Unconfined in production unless for a rare,
documented case. Make suspend functions main-safe: move blocking work into
withContext(Dispatchers.IO) so callers on Main are never blocked. Inject CoroutineDispatcher
as a constructor parameter (default to real dispatcher; replace with TestDispatcher in tests).Job() or SupervisorJob() directly to builders (e.g. launch(Job()) { }). Use
supervisorScope { } or a scope defined with SupervisorJob() for supervisor semantics. When
running independent tasks with awaitAll, use supervisorScope instead of coroutineScope so
one failure does not cancel sibling deferreds.CancellationException; rethrow it in catch blocks.CancellationException for domain errors; use normal exceptions instead.yield(), ensureActive(), or while (isActive)
with delay(interval) so the coroutine responds to cancellation.finally, use withContext(NonCancellable) { }.scope.cancel(); use coroutineContext.job.cancelChildren() to
stop only children while keeping the scope alive.withTimeoutOrNull over withTimeout to avoid unintentionally cancelling the parent
scope. If using withTimeout, catch TimeoutCancellationException explicitly. Always ensure
resources opened inside withTimeout are cleaned up in finally.launch propagate to CoroutineExceptionHandler; in async, the
exception is stored in the Deferred and only thrown on await(). Always call await() on
async blocks to avoid silently losing exceptions.CoroutineExceptionHandler at scope level for launch uncaught exceptions.kotlinx-coroutines-test: runTest, virtual time, advanceTimeBy,
advanceUntilIdle, and inject TestDispatcher/StandardTestDispatcher; avoid real delay()
with runBlocking. Replace Dispatchers.Main using Dispatchers.setMain(TestDispatcher()) in
@Before and Dispatchers.resetMain() in @After.produce { } for channels so they close when the coroutine ends. Do not share
consumeEach across multiple consumers; use for (x in channel) per consumer.flow { } builder non-blocking; use flowOn(Dispatchers.IO) or suspend APIs.StateFlow for shared UI state (replays last value); use SharedFlow for events with
explicit replay, extraBufferCapacity, and onBufferOverflow configuration.collectLatest only when cancelling in-progress work is intentional (e.g. search); use
collect when each item must be processed to completion.repeatOnLifecycle(Lifecycle.State.STARTED) or
flowWithLifecycle to stop collection when the UI goes to background.When analyzing Kotlin projects for coroutine issues:
Read on build.gradle.kts / build.gradle for Kotlin version, kotlinx-coroutines-*
dependencies, and kotlinx-coroutines-test.Grep for CoroutineScope, GlobalScope, runBlocking, Dispatchers,
viewModelScope, lifecycleScope to locate usage patterns.Each references/ref-*.md file is self-contained (Bad Practice, Recommended, Why, Quick fix). Open the linked file directly — no dependency on repo docs when the skill is installed standalone.
| Topic / Error / Question | Reference file |
|---|---|
| GlobalScope, scope lifetime, "where should I launch?" | ref-1-1-global-scope.md |
| async without await, fire-and-forget with async | ref-1-2-async-without-await.md |
| Breaking structured concurrency, launching in external scope from suspend | ref-1-3-breaking-structured-concurrency.md |
| awaitAll exception propagation, coroutineScope vs supervisorScope for parallel tasks | ref-1-4-awaitall-exception-propagation.md |
| coroutineScope { launch { } } as last line, "wait vs don't wait" | ref-2-1-launch-last-line-coroutine-scope.md |
| runBlocking inside suspend, blocking in coroutines | ref-2-2-runblocking-in-suspend.md |
| Blocking I/O on Default/Main, wrong Dispatchers for I/O | ref-3-1-blocking-wrong-dispatchers.md |
| Main-safe suspend functions, suspend blocking caller thread, ANR | ref-3-2-main-safe-suspend.md |
| Dispatchers.Unconfined in production | ref-3-2-dispatchers-unconfined.md |
| Job() / SupervisorJob() passed to launch/async/withContext | ref-3-3-job-context-builders.md |
| Injecting Dispatchers, hardcoded dispatcher, flaky tests, testability | ref-3-5-inject-dispatchers.md |
| Cancellation in loops, long loops not responding to cancel | ref-4-1-cancellation-intensive-loops.md |
| Periodic / repeating work, polling, zombie coroutine, infinite loop without isActive | ref-4-2-periodic-repeating-work.md |
| Swallowing CancellationException, catch Exception and cancel | ref-4-2-swallowing-cancellation-exception.md |
| Suspend in finally, cleanup that needs to suspend | ref-4-3-suspend-cleanup-noncancellable.md |
| Reusing scope after cancel(), cancelChildren vs cancel | ref-4-4-reusing-cancelled-scope.md |
| withTimeout scope cancellation, TimeoutCancellationException, withTimeoutOrNull | ref-4-6-withtimeout-scope-cancellation.md |
| withTimeout resource cleanup, resource leak on timeout, finally, NonCancellable | ref-4-7-withtimeout-resource-cleanup.md |
| SupervisorJob() in a single builder | ref-5-1-supervisor-job-single-builder.md |
| CancellationException for domain errors (e.g. UserNotFound) | ref-5-2-cancellation-exception-domain-errors.md |
| CoroutineExceptionHandler vs async, exceptions in async stored in Deferred until await() | ref-5-3-exception-handler-async.md |
| Slow tests, real delay() in tests | ref-6-1-slow-tests-real-delays.md |
| Uncontrolled fire-and-forget in tests, can't wait in tests | ref-6-2-uncontrolled-fire-and-forget-tests.md |
| Dispatchers.Main in tests, setMain/resetMain, CI flaky tests | ref-6-3-setmain-resetmain.md |
| Channel not closed, manual Channel without close() | ref-7-1-channel-close.md |
| consumeEach with multiple consumers | ref-7-2-consume-each-multiple-consumers.md |
| Architecture, layers (Data/Domain/Presentation), suspend vs callbacks | ref-8-architecture-patterns.md |
| Lifecycle-aware Flow collection (Android), repeatOnLifecycle, flowWithLifecycle | ref-8-2-lifecycle-aware-flow.md |
| Blocking in flow { }, Thread.sleep in flow, flowOn | ref-9-1-flow-blocking-call.md |
| Cold vs hot flows, StateFlow, SharedFlow, shareIn, stateIn, collect | ref-9-2-cold-vs-hot-flows.md |
| collectLatest semantics, cancels previous block, search vs complete work | ref-9-3-collect-latest.md |
| SharedFlow configuration, replay, extraBufferCapacity, onBufferOverflow, backpressure | ref-9-4-shared-flow-configuration.md |
| suspendCoroutine without cancellation, callback bridge | ref-101-interop-suspend-cancellable.md |
| callbackFlow without awaitClose, listener leak | ref-102-interop-callbackflow-awaitclose.md |
| channelFlow vs callbackFlow, wrong flow builder | ref-103-interop-channelflow-callbackflow.md |
| Future.get in coroutine, CompletableFuture blocking | ref-104-interop-future-get.md |
| MutableStateFlow exposed publicly, UDF violation | ref-95-flow-mutable-exposed.md |
| Flow chain missing catch, launchIn/collect without catch | ref-96-flow-missing-catch.md |
| runBlocking in tests, runTest virtual time | ref-64-test-runtest.md |
| Dispatchers.IO in commonMain, KMP crash | ref-111-kmp-dispatchers-io.md |
| runBlocking in commonMain, KMP deadlock | ref-112-kmp-runblocking.md |
| collectAsState without lifecycle, Compose background collection | ref-83-compose-collect-lifecycle.md |
| rememberCoroutineScope for init, LaunchedEffect | ref-84-compose-remember-scope-init.md |
| Side effect in composable body, recomposition | ref-85-compose-side-effect.md |
| Hardcoded Dispatchers in class, testability | ref-65-test-hardcoded-dispatcher.md |
| advanceUntilIdle missing in runTest, flaky test | ref-66-test-not-completed.md |
| flatMapLatest vs merge vs concat, Flow operator choice | ref-910-flow-flatmap-choice.md |
| SharedFlow one-shot events, Channel for navigation | ref-911-flow-oneshot-events.md |
| synchronized in coroutine, Mutex | ref-121-concur-synchronized.md |
| Sequential async await, wasted Deferred | ref-15-concur-sequential-async.md |
| stateIn Eagerly on ViewModel, WhileSubscribed | ref-97-flow-statein-eagerly.md |
| launchIn GlobalScope, unstructured Flow collection | ref-98-flow-launchin-unstructured.md |
| Side effect in map operator, onEach for effects | ref-99-flow-sideeffect-map.md |
| MDC not propagated, MDCContext | ref-37-backend-mdc.md |
| Blocking JDBC in backend coroutine, Dispatchers.IO | ref-131-backend-blocking.md |
| Missing CoroutineName, debugging | ref-141-debug-coroutine-name.md |
| Redundant nested withContext, same dispatcher twice | ref-36-concur-redundant-withcontext.md |
| MainScope without cancel, KMP presenter leak | ref-113-kmp-mainscope-without-cancel.md |
| Shared mutable state in launch, race on ArrayList | ref-122-concur-shared-mutable-state.md |
| withTimeout cancels parent scope, use withTimeoutOrNull | ref-4-6-withtimeout-scope-cancellation.md |
| Job in builder, SupervisorJob as argument | ref-3-3-job-context-builders.md |
| External scope launch from suspend, structured concurrency break | ref-1-3-breaking-structured-concurrency.md |
| Inline CoroutineScope, scope(CoroutineScope(...)) | ref-1-3-breaking-structured-concurrency.md |
| Scope reuse after cancel, launch after scope.cancel() | ref-4-4-reusing-cancelled-scope.md |
| ViewModelScope leak, collect without lifecycle | ref-8-2-lifecycle-aware-flow.md |
launch – Fire-and-forget or UI-triggered work that does not return a value
// Use for: Work that does not need a result; lifecycle-bound to scope
viewModelScope.launch {
updateUI(loadData())
}async / await – Parallel work when you need a return value
// Use for: Deferred result; always await (or awaitAll) to preserve structure
coroutineScope {
val a = async { fetchA() }
val b = async { fetchB() }
combine(a.await(), b.await())
}coroutineScope – Structured child work inside a suspend function
// Use for: Subtasks that must complete or cancel with the current scope
suspend fun loadAll() = coroutineScope {
val one = async { loadOne() }
val two = async { loadTwo() }
Pair(one.await(), two.await())
}withContext – Switch dispatcher or run cleanup (e.g. NonCancellable)
// Use for: Blocking I/O off Main/Default; cleanup in finally
withContext(Dispatchers.IO) { readFile(path) }
withContext(NonCancellable) { db.close() }supervisorScope – Children do not cancel each other on failure
// Use for: Independent child jobs (e.g. multiple UI updates)
supervisorScope {
launch { updateA() }
launch { updateB() }
}produce – Channel that closes when the coroutine ends
// Use for: Single producer; automatic close when scope completes
fun CoroutineScope.flowFromApi() = produce {
for (item in api.stream()) send(item)
}Scenario: Single network request with UI update
viewModelScope.launch {
val data = withContext(Dispatchers.IO) { repo.fetch() }
updateUI(data)
}Scenario: Multiple parallel requests
coroutineScope {
val users = async { repo.getUsers() }
val posts = async { repo.getPosts() }
show(users.await(), posts.await())
}Scenario: Cancellation-friendly loop
for (i in list) {
yield() // or ensureActive()
process(i)
}coroutineScope + async/launch inside suspend; avoid
launching in external scope from suspend unless documented. For independent tasks, use
supervisorScope + awaitAll so one failure does not cancel siblings.launch. Always call await() on
every Deferred; exceptions are only thrown at await(), not caught by CoroutineExceptionHandler.withContext(IO) internally). Inject
dispatchers for testability.while(isActive) + delay for
repeating work; use yield/ensureActive in long loops; use withContext(NonCancellable) for
suspend cleanup in finally. Prefer withTimeoutOrNull; ensure resources are cleaned up on
timeout.runTest, TestDispatcher, advanceTimeBy; avoid real delay()
in tests. Replace Dispatchers.Main with setMain/resetMain for reliable CI tests.produce; if using Channel manually, document when close() is called;
one consumer per channel with for (x in channel).flow { } non-blocking (use flowOn); use StateFlow for state, SharedFlow
for events with explicit buffer/overflow config; use collectLatest only when cancelling
in-progress work is intentional.repeatOnLifecycle(STARTED) or flowWithLifecycle
so collection stops when UI is in background.Structure every code-review or refactor response as:
For conceptual-only questions, skip erroneous/optimized snippets and keep analysis and explanation.
© santimattius, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 59 other files (references) in kotlin-coroutines-skill of santimattius/structured-coroutines.
Open the folder on GitHubat commit 1037e0c
Kotlin Coroutines Skill next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Kotlin Coroutines Skill this skillsantimattius/structured-coroutines | 158 | — | ~6.8k | Automated safety check: Pass | Apache-2.0 | |
| Android Developmentdpconde/claude-android-skill | 336 | — | ~1.7k | Automated safety check: Pass | MIT | |
| Claude Android NinjaDrjacky/claude-android-ninja | 124 | — | ~5.2k | Automated safety check: Pass | Apache-2.0 | |
| Expo Brownfield Integrationmweinbach/agent-coworker | 156 | 2 repos | ~900 | Automated safety check: Notes | Custom licence | |
| Jugg Android Dev Loopniki914/zafiro | 241 | — | ~2k | Automated safety check: Pass | MIT | |
| Build Foremannekomangaorg/Neko | 2.8k | — | ~807 | Automated safety check: Pass | Apache-2.0 |
dpconde/claude-android-skill
Create production-quality Android applications following Google's official architecture guidance and NowInAndroid best practices.
Drjacky/claude-android-ninja
Build and migrate Android apps with Kotlin, Jetpack Compose, MVVM, Hilt, Room 3 (KSP, SQLiteDriver, Flow/suspend DAOs), Navigation3, and multi-module Gradle.
mweinbach/agent-coworker
Helps add Expo and React Native to an existing native iOS or Android app, and choose between a prebuilt AAR or XCFramework and a fully integrated build.
niki914/zafiro
A skill your agent uses when editing source files (Java/Kotlin/XML/layout/AndroidManifest/Gradle) in a Android project, or when user asks to build/deploy/verify an Android app.
nekomangaorg/Neko
Optimizes Gradle build scripts, compilation times, and Android Studio sync performance.
hyochan/react-native-nitro-sound
Build and run device-backed Android end-to-end checks for react-native-nitro-sound permissions, recording, playback, listeners, pause/resume, seek, speed, audio focus, lifecycle behavior, and rapid…
Categories
Load, when a developer writes, reviews, or debugs Kotlin coroutine code and needs help spotting concurrency bugs — GlobalScope leaks, runBlocking in suspend, missing Flow catch, hardcoded or wrong…. Kotlin Coroutines Skill is an agent skill from santimattius/structured-coroutines. Load, when a developer writes, reviews, or debugs Kotlin coroutine code and needs help spotting concurrency bugs — GlobalScope leaks, runBlocking in suspend, missing Flow catch, hardcoded or wrong dispatchers, unhandled timeouts, cancellation and structured-concurrency mistakes — or asks how to make async Kotlin testable.
Kotlin Coroutines Skill fits situations like: tasks that involve Android development.
Run `npx skills add santimattius/structured-coroutines --skill kotlin-coroutines-skill -a claude-code`. Or copy the skill folder (kotlin-coroutines-skill in santimattius/structured-coroutines) into .claude/skills/kotlin-coroutines-skill in your project. Claude Code loads it when a task matches its description.
Run `npx skills add santimattius/structured-coroutines --skill kotlin-coroutines-skill -a codex`. Or copy the skill folder (kotlin-coroutines-skill in santimattius/structured-coroutines) into .agents/skills/kotlin-coroutines-skill in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add santimattius/structured-coroutines --skill kotlin-coroutines-skill -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/kotlin-coroutines-skill, .gemini/skills/kotlin-coroutines-skill, .github/skills/kotlin-coroutines-skill and .opencode/skills/kotlin-coroutines-skill in your project.
SKILL.md names no scripts, command-line tools or credentials: Kotlin Coroutines Skill is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Kotlin Coroutines Skill is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 6.8k tokens (SKILL.md is roughly 27k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 22k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Kotlin Coroutines Skill: Android Development (dpconde/claude-android-skill, 336 stars), Claude Android Ninja (Drjacky/claude-android-ninja, 124 stars), Expo Brownfield Integration (mweinbach/agent-coworker, 156 stars) and Jugg Android Dev Loop (niki914/zafiro, 241 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
santimattius (a GitHub user) maintains it in santimattius/structured-coroutines, which has 158 GitHub stars. The repository was last updated on September 12, 2026.
Source: santimattius/structured-coroutines on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.