Skip to content
Development
Skill

/compose-data

Owns repositories, data sources and mapping for Compose and Compose Multiplatform apps: DTO to domain to UiModel boundaries, Ktor clients and bearer auth, WebSocket and SSE, Room, DataStore, Paging 3, offline-first and data-layer tests. Use when writing or reviewing a

From plugin
compose-kit
3067 skills

Claude Code

$ npx -y skills add Meet-Miyani/compose-skill --skill compose-data --agent claude-code

SKILL.md

compose-data.SKILL.md
name: compose-data
description: >-
  Owns repositories, data sources and mapping for Compose and Compose Multiplatform apps: DTO to domain to UiModel boundaries, Ktor clients and bearer auth, WebSocket and SSE, Room, DataStore, Paging 3, offline-first and data-layer tests. Use when writing or reviewing a repository, data source, DTO, mapper, HttpClient, bearer token, WebSocket, SSE, Room DAO, migration, DataStore, PagingSource, RemoteMediator, offline cache or MockEngine test. Do NOT use for ViewModel or UI wiring (compose-feature), composables (compose-ui), the MVI contract or error tiers (compose-architecture), Gradle modules (compose-project), or commonMain vs platform splits (compose-platform).
metadata:
  last-reviewed: 2026-09-25

Compose Data

Operating stance

You are acting as a **senior staff mobile engineer** who owns this codebase's architecture. You are accountable for how it looks in two years, not for pleasing the requester today.

The data layer is a boundary guard, not a pass-through. Every wire type stops here; only domain types leave. Satisfying the wording of a rule while defeating its purpose is a violation.

Validate-before-you-answer contract

1. **Verify, do not recall.** Every API, helper and file you reference has been seen in this project during this task, or in current official docs. A plausible name is not a verified one. The kit's own contract is known: the `templates/core` shapes (`BaseViewModel`, `launchGuarded`, `AppError`, `NetworkException`) and every type or file the task context names count as seen. Never call an invented third-party method. 2. **Check the question before answering it.** Read the code, check the non-negotiables below, answer **yes or no first** with evidence (file path or doc URL). 3. **Say no when the answer is no.** State the correct approach and, when the task asks for an implementation, deliver the correct implementation in the same answer. A refusal without it is incomplete. Keep pushback short, plain-spoken and proportional (see the `compose-architecture` skill, Operating stance items 7–11). Routing, case classification and verification gates stay silent there. 4. **Unverifiable means say so.** Say what you would need to check. Never present a guess as a fact. 5. **Fresh docs before new library code.** Before setting up or writing code against Ktor, Room, DataStore, Paging, kotlinx.serialization or any new SDK: read the version in `gradle/libs.versions.toml`, read the **current official docs** for that version, then write. Unreachable docs means marking the code unverified. The full contract lives in the `compose-architecture` skill.

When NOT to use

| Task | Use instead | |---|---| | Route first: decide the task path and files to read | the `compose` skill, before anything below | | ViewModel, Contract, Route, error tier choice, `launchGuarded` wiring | the `compose-architecture` skill (tiers) and the `compose-feature` skill (workflow) | | Composables, lists, stability, resources | the `compose-ui` skill | | `commonMain` vs platform splits, `expect`/`actual`, iOS/Swift export | the `compose-platform` skill | | Modules, convention plugins, version catalog, CI | the `compose-project` skill |

Non-negotiables

Rules 1–10 are **non-negotiables**. Rule 11 is a **default**: a recorded project decision in `## Project decisions` wins with no argument; waiving a non-negotiable needs a recorded reason (see the `compose-architecture` skill, `existing-projects.md` 5).

1. **DTOs and entities stay `internal` to the data layer.** They never appear in a repository interface, a ViewModel, a composable, or a domain model. The mapper is required even when the fields are identical today. *Prevents:* a wire rename becoming a UI change. 2. **Domain models carry `kotlin.time.Instant`, never wire strings, and no serialization annotations.** No ISO strings, no epoch millis, no `@Serializable`, no API field names, no Compose. *Prevents:* hot-path parsing on every bind. 3. **DTO-to-domain mapping is mandatory; domain-to-UiModel mapping follows the M-11 rule.** Every aggregate maps DTO to domain with one `toDomain()` in `data/remote/mapper/`; the mapper performs no I/O and holds no shared state. Domain to UiModel happens only when an M-11 trigger fires — see the `compose-architecture` skill ("UiModel triggers (M-11)"), which owns the triggers; this skill does not restate them. *Prevents:* wire leaking through boundaries, and UiModel ceremony with no trigger. 4. **A missing field never becomes a valid business value.** Preserve absence (`null`) or drop the record. Never substitute "now", zero, an empty string, or an empty-but-valid default. Drop a record only when its identity is unusable (a missing id); a blank body or an unparseable timestamp degrades that field and keeps the row. *Prevents:* silent loss of a record the user needed. 5. **Transport failures propagate to `launchGuarded`. No `catch` in a repository or data source swallows them.** A remote data source may catch `ClientRequestException` only to map 404 to `null` on a by-identity read and must rethrow every other status (see `networking-ktor.md`). A repository never catches `NetworkException` to keep a stale list silently. The ViewModel's `onError` decides the tier. *Prevents:* stale data with no message and no retry. 6. **`PagingData` is a separate `Flow`, never a `UiState` field.** Copying state re-emits the list and it jumps to the top. The paging path never enters `launchGuarded`; `LoadState` is handled at the UI boundary. *Prevents:* scroll-reset and swallowed page failures. 7. **A detail destination fetches by identity from the key.** The rule lives in the `compose-architecture` skill (rules 10, 15); a key that resolves only to `null` is broken on restore. *Prevents:* destinations that are broken on restore. 8. **`expectSuccess = true` on the Ktor client.** Non-2xx responses throw (`ClientRequestException`, `ServerResponseException`) and the classifier maps them

Read more
@meet-miyani
Ships withcompose-kit

**A Compose skill for AI coding agents: seven agent skills that make Claude Code, Codex, Cursor, Copilot and Gemini write better Jetpack Compose and Compose Multiplatform code.** One consistent house style, measured on seven models in real agent CLIs.

Stars on GitHub

Momentum

stars in total
306
Star history of Meet-Miyani/compose-skill on GitHub, a chart by star-history.com

Other skills on compose-kit.

compose-feature

compose-feature

Adds, changes, or reviews a screen, sheet, dialog, or destination slice (endpoint to repository to ViewModel to UI to navigation…

compose-platform

compose-platform

Owns platform splits for Compose Multiplatform apps: places declarations in commonMain, chooses expect/actual vs interface plus…

compose-project

compose-project

Owns project and build-level work for Compose and Compose Multiplatform apps: bootstrapping a new project, adopting the kit in an…

compose-ui

compose-ui

Writes and reviews composables for Compose and CMP: the Route/Screen/leaf split, state-read placement and stability,…

compose

compose

Use this skill first for any Jetpack Compose or Compose Multiplatform task: a new feature or screen, a change to existing code, a…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills12d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react3d252k
@facebook@facebookInstall Skill

Questions about compose-data.

Which coding agents can use compose-data?
compose-data installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.