compose-skill について
Jetpack Compose と Compose Multiplatform の開発を支援するスキルで、アーキテクチャ、状態管理、UI、クロスプラットフォーム設計を扱います。既存のプロジェクト規約を尊重し、依存関係の追加前に対応ターゲットと API の確認を促します。
主な機能
- 01MVI と MVVM の設計指針
- 02状態と副作用のモデリング
- 03Compose UI の境界と実践法
- 04クロスプラットフォーム共有の指針
- 05依存関係とターゲット対応の確認
活用シーン
- 01Compose 画面の状態とイベントの流れを設計
- 02コンポーザブル内の業務ロジックや状態を確認
- 03依存関係が必要なターゲットに対応するか確認
- 04Compose Multiplatform のコード分割を計画
MCP 対応
利用可能な場合は依存関係の調査にドキュメント MCP ツールを推奨し、呼び出し前にツール名とパラメーターを確認するよう案内します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ meet-miyani/ compose-skill --skill compose-skillインストール後、Claude Code で/compose-skillを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.gitignoreLICENSEREADME.md.cursor/rules/reference-file-standards.mdc.github/workflows/release.ymlvalidate.ymlagents/openai.yamlreferences/accessibility.mdanimations-advanced.mdci-cd-distribution.mdanimations.mdcoroutines-flow-advanced.mdcompose-essentials.mdclean-code.mdarchitecture.mdcross-platform.mdanti-patterns.mddatastore.mddependency-injection.mdcoroutines-flow.mdimage-loading.mdhilt.mdios-swift-interop.mdmaterial-design.mdlists-grids.mdgradle-build.mdmvvm.mdkoin.mdnavigation-2-di.mdnavigation-3-di.md詳細
Jetpack Compose と Compose Multiplatform
このスキルでは、アーキテクチャや状態管理から、UI、ネットワーク通信、永続化、パフォーマンス、アクセシビリティ、クロスプラットフォームでの共有、ビルド設定、配布まで、Compose アプリ開発のライフサイクル全体を扱います。Jetpack Compose と Compose Multiplatform は、同じコア API とメンタルモデルを共有しています。すべての Jetpack ライブラリが commonMain で動作するわけではありません。Android 専用のものも多く残っています。AndroidX ライブラリの一部は現在、マルチプラットフォーム向けのアーティファクト(例:lifecycle-viewmodel、lifecycle-runtime-compose、datastore-preferences)を公開していますが、利用可能かどうかや API の範囲はバージョンによって異なります。commonMain に Jetpack/AndroidX の依存関係を追加する前に、Maven Central またはライブラリの公式ドキュメントを確認し、必要なすべてのターゲット向けにアーティファクトが公開されていることを確かめてください。 CMP では、プラットフォーム固有のコードに expect/actual またはインターフェースを使用します。推奨するアーキテクチャは MVI(Model-View-Intent)ですが、既存プロジェクトの規約に合わせて対応します。
既存プロジェクトの方針
移行を無理強いしないでください。 プロジェクトがすでに独自の規約(異なる基底クラス、命名規則、ファイル構成など)に従って MVI を採用している場合は、その方針を尊重してください。プロジェクトで既に使われているパターンに合わせます。重要なのは、特定の基底クラスやフレームワークではなく、Event、State、Effect を使った単方向データフローというアーキテクチャパターンです。構造の変更は、ユーザーから依頼があった場合、または既存コードに明らかなアーキテクチャ上の問題(コンポーザブル内のビジネスロジック、分散した状態変更など)がある場合にのみ提案してください。
ワークフロー
Jetpack Compose または Compose Multiplatform のコードを扱う際は、次の手順に従ってください。
- まず既存コードを読んで状況を把握します — 規約、基底クラス、レイアウトを確認します。小規模な UI やロジックに関する依頼では、時間を節約するため、すぐに関係するファイルだけを読みます。構造的なリファクタリングを求められていない限り、プロジェクト全体のアーキテクチャを把握しようとしないでください。
- 対象となる課題を特定します — アーキテクチャ、状態のモデリング、パフォーマンス、ナビゲーション、DI、アニメーション、クロスプラットフォーム対応、テストのどれに関するものかを確認します。
- 以下のコアルールを適用します — このファイルに記載された判断の指針とデフォルト設定で、ほとんどのケースに対応できます。
- 適切なリファレンスを参照します — より詳しいガイダンスが必要な場合にのみ、
references/から該当するファイルを読み込みます。適切なファイルを選ぶには、「詳細リファレンス」セクションのクイックルーティングを使用してください。 - 推奨する前に依存関係を確認します — 依存関係を追加またはアップグレードする前に、ドキュメント MCP ツールまたは公式ドキュメントで座標、ターゲットのサポート、API の仕様を確認してください(依存関係の確認ルールを参照)。
- 状況に応じてアンチパターンを指摘します — ユーザーのコードがベストプラクティスに反している場合は、本番コード向けであることを踏まえて指摘します。手早いプロトタイプや軽微な UI 調整では、厳格なルールを説くよりも、具体的な質問への回答を優先してください。
- 正しく、最小限の解決策を記述します — 過剰に複雑にしないでください。汎用フレームワークより、機能に特化したコードを優先します。
依存関係の検証ルール
新しい依存関係の追加やバージョンアップを推奨する前に、次の点を検証してください。
- 座標 — 正確な Maven 座標(
group:artifact:version)が存在し、最新であることを確認します。 - ターゲットのサポート — アーティファクトがプロジェクトのターゲット(Android、iOS、Desktop、
commonMain)をサポートしていることを確認します。検証せずに、Jetpack ライブラリがcommonMainで動作すると想定しないでください。 - API の形状 — 使用する予定の API が、そのバージョンに実際に存在することを確認します。関数シグネチャ、パラメーター名、戻り値の型はメジャーバージョン間で変わることがあります。
検証方法:
- ドキュメント MCP ツール(推奨) — ドキュメント MCP サーバー(Context7 など)が利用できる場合は、まずツールの正確な名前とスキーマを確認してから、ライブラリの最新の公式ドキュメントを取得します。
- 公式ドキュメント — ライブラリの公式ドキュメントまたはリリースノートを検索します。
- Maven Central / Google Maven — アーティファクトの提供状況とサポート対象プラットフォームを確認します。
検証できない場合(ドキュメントツールがない、ネットワークにアクセスできない、ドキュメントを利用できない場合)でも、標準または既知の最新の依存関係スニペットを提示してください。ユーザーが作業を進められるよう、// Verify latest version のような短いコメントを追加します。
最新のドキュメントの取得
新しい依存関係を追加するとき、メジャーバージョンをアップグレードするとき、または最新の API パターンを検証するときは、利用可能であればドキュメント MCP ツール(Context7 など)を使用してください。呼び出す前に、ツールの正確な名前とパラメータースキーマを確認してください。ツール名は環境によって異なります。
- ライブラリ ID を解決する — ツールで解決手順が必要な場合は、まずそれを呼び出します。
- ドキュメントを照会する — 解決済みの ID を指定し、具体的な質問をします。
代替方法:ユーザーはプロンプトに use context7(または同等の指示)を追加できます。同梱のリファレンスは、アーキテクチャパターンと MVI ガイダンスの主要な情報源です。API 固有およびバージョン固有の質問には、ドキュメントツールを使用してください。
コアアーキテクチャ:MVI または MVVM
MVI と MVVM はどちらも一方向のデータフローを使用します。UI が状態をレンダリング → ユーザーが操作 → ViewModel が状態を更新 → UI が再レンダリングします。異なるのは、UI の操作が ViewModel に届く方法です。
- MVI:
sealed interface Eventと単一のonEvent()エントリーポイント - MVVM:名前付きのパブリック関数(
onTitleChanged()、save())
どちらのパターンも次を使用します。
- State — 画面を完全に記述する不変のデータクラス。
StateFlowを介して所有されます。 - Effect —
Channelを介して配信される一度限りのコマンド(画面遷移、スナックバー、共有)
デフォルトの推奨事項: 一貫性がある場合は、プロジェクトで既に採用されているパターンを維持してください。新規プロジェクトでは、チームの好みと画面の複雑さに基づいて選択します。判断の指針についてはアーキテクチャと状態管理を参照し、実装の詳細についてはmvi.mdまたはmvvm.mdを参照してください。
UI レンダリングの境界
次の境界は MVI と MVVM の両方に適用されます。
- Route コンポーザブル:ViewModel を取得し、
collectAsStateWithLifecycle()で状態を収集し、CollectEffect(compose-essentials.mdを参照)でエフェクトを収集し、ナビゲーション/スナックバー/プラットフォーム API をバインドします。 - Screen コンポーザブル:ステートレスなレンダラーです。状態とコールバック(MVI:
onEvent、MVVM:個別のコールバック)を受け取り、画面をレンダリングし、リーフコンポーザブル用にコールバックを適応させます。 - Leaf コンポーザブル:サブ状態をレンダリングし、具体的なコールバックを発行します。フォーカス、スクロール、アニメーションなど、画面内に限定された最小限の視覚状態のみを保持します。
判断のヒューリスティクス
- コンポーズ関数は状態を描画してイベントを発行し、ビジネスルールの判断は行いません
- 状態から導出できる値は、非同期処理/永続化/パフォーマンス上の理由が正当化されない限り、重複して保存しないでください
- ViewModel でのイベント処理が状態遷移を担い、コンポーズ関数は状態を変更しません
- UI ローカルの状態が許容されるのは、フォーカス、スクロール、アニメーションの進行状況、展開切り替えなど、一時的な視覚上の関心事に限られます
- ビジネスロジックが依存しない限り、アニメーション専用のフラグを画面のグローバル状態に含めないでください
- リーフコンポーズ関数には、可能な限り範囲を絞った状態を渡してください
- MVI:
onEvent()を唯一の入口として実装します。MVVM:ユーザー操作ごとに名前付き関数を実装します - リポジトリ呼び出しごとにユースケースを追加しないでください
- クロスプラットフォームでの共有では、プラットフォームの動作よりもビジネスロジックとプレゼンテーション状態を優先します
- 再コンポーズを最小限に抑えるには、まず状態の形状と読み取り境界を適切にし、その次に Compose API を活用します
- プロジェクトに既存の MVI 基底クラスまたはパターンがある場合は、それを使用してください。競合する抽象化を導入しないでください
状態のモデリング
計算機/フォーム画面では、状態を次の4つに分けます。
- 編集可能な入力 — ユーザーが編集する生のテキストと選択値
- 導出された表示/ビジネス値 — 解析、検証、計算された値
- 永続化されたドメインスナップショット — 変更検知またはリセットに使用する保存済みエンティティ
- 一時的な UI 専用状態 — 純粋に視覚上のもので、ビジネス上の意味を持たない状態
| 関心事 | 格納場所 | 例 |
|---|---|---|
| 生のフィールドテキスト | state フィールド | "12"、"12."、"" |
| 解析/導出された値 | state の計算プロパティまたはフィールド | val hasRequiredFields: Boolean |
| 検証 | state.validationErrors など | mapOf("name" to "Required") |
| 読み込み/更新 | state のフラグ | isSaving = true |
| 一度限りの UI コマンド | Channel 経由の Effect | スナックバー、画面遷移、共有 |
| スクロール/フォーカス/アニメーション | ローカルな Compose 状態 | LazyListState、フォーカスリクエスター |
推奨するデフォルト
プロジェクトで一貫性のある別のパターンをすでに採用している場合を除き、以下を適用してください。
| 関心事 | デフォルト |
|---|---|
| ViewModel | 画面ごとに1つの ViewModel(CMP では commonMain、Android 専用では機能パッケージ)。MVI:onEvent(Event) を入口にします。MVVM:名前付き関数を使います |
| 状態の信頼できる情報源 | ViewModel が所有する StateFlow<FeatureState> |
| イベント処理 | MVI:when 式を使った onEvent(event)。MVVM:名前付き関数。どちらもユーザー操作を状態更新、エフェクトの発行、非同期処理の起動に対応付けます |
| 副作用 | UI が消費する一度限りの処理(画面遷移、スナックバー)には、Channel<Effect>(Channel.BUFFERED) で送信する Effect を使います。非同期処理(ネットワーク、永続化)は viewModelScope で起動します |
| 非同期読み込み | 以前のコンテンツを保持し、読み込みフラグを切り替え、古くなったジョブをキャンセルし、完了時に状態を更新します |
| シンプルな UI 契約 | 描画用のプロパティを受け取り、明示的なコールバックを発行し、一時的な視覚状態のみをローカルに保持します |
| リソースへのアクセス | 状態には意味のあるキー/列挙型を保持し、文字列/アイコンの解決は UI の近くで行います。CMP では Res.string / Res.drawable を使用します(Android の R は使用しません)。リソース を参照してください |
| プラットフォームの分離 | CMP:commonMain で共有し、expect/actual(build.gradle.kts で Kotlin 1.9 と 2.0 以降を確認するか、ユーザーに尋ねます)またはインターフェースを使用します。デフォルトの DI には Koin を使用します。Android 専用:標準的なパッケージ構成を使い、DI には Hilt または Koin を使用します |
| ナビゲーション | ViewModel が意味のあるナビゲーションエフェクトを発行し、ルート/ナビゲーション層が実行します |
| 永続化(設定) | キーと値の設定には commonMain の DataStore Preferences、構造化された設定オブジェクトには Typed DataStore(JSON)、リレーショナルデータ/クエリ対象データには Room を使用します。DataStore を参照してください |
| テスト | commonTest で Turbine を使用して ViewModel のイベント→状態→エフェクトをテストします。バリデーター/計算処理は純粋関数としてテストし、プラットフォームバインディングはターゲットごとにテストします |
Do / Don't クイックリファレンス
行うこと
- パース済みの値とは別に、編集可能な生テキストを保持する
- 状態を不変にし、等価性を判定しやすくする
- 可能な場合は、変更のないネストされたオブジェクトを再利用する
- イベント処理からプラットフォームを呼び出すのではなく、セマンティックなエフェクトを発行する
- 更新中も古いコンテンツを保持する
- ドメインデータから UI 状態への変換は、プレゼンテーション境界の近くで行う
- 機能に固有の ViewModel 名を使用する
- リスト項目のキーには、安定したドメイン ID を使用する
- ファイルの先頭ですべての型と関数をインポートする。名前の衝突を解決するには
import ... as ...のエイリアスを使用する - 何も変わっていない場合は状態を更新しないなど、不要な状態の発行を防ぐ
- プロジェクトで既に採用されている MVI の規約に従う
行わないこと
- コンポーザブルの本体で数値をパースする
- コンポーザブルからネットワークリクエストを実行する
MutableState、コントローラー、ラムダ、プラットフォームオブジェクトを画面状態に保持する- スナックバーやナビゲーションを状態内の「一度だけ消費する」ブール値で表現する。エフェクトを使用する
- ささいな視覚的切り替えをすべて ViewModel の状態に保持する
- すべての子コンポーザブルに状態全体を渡す
- すべてのリポジトリ呼び出しをユースケースクラスでラップする
- 更新中に画面全体をスピナーで覆う
- 動作しているコードベースに、別のアーキテクチャや基底クラスへの移行を強制する
- パッケージの完全修飾パスをインラインで使用する(例:
com.example.pkg.SomeClass.method())。必ずファイルの先頭でインポートする
詳細なリファレンス
基本的な Compose の使い方では、リファレンスファイルを読み込まないでください。 必要な UI やロジックの構築方法を既に把握している場合は、すぐにコードを書いてください。高度な概念(例:Paging 3、Nav 3 のセットアップ)がタスクに含まれる場合に限り、リファレンスファイルを1つだけ読み込んでください。 以下から適切なファイルを選び、推測でファイルを読み込まないでください。
クイックルーティング
- 再コンポーズの頻度が高すぎる場合、安定性、または Compose Compiler のメトリクス → performance.md
- Channel と SharedFlow の違い、Flow 演算子、構造化された並行処理、または例外処理 → coroutines-flow.md
- バックプレッシャー、callbackFlow、Mutex/Semaphore、または Turbine によるテスト → coroutines-flow-advanced.md
- Nav 3 のルート、タブ、シーン、ディープリンク、またはバックスタックのパターン → navigation-3.md
- Nav 2 の NavHost、タブ、ディープリンク、ネストされたグラフ、またはアニメーション → navigation-2.md
- Hilt または Koin とナビゲーションの連携 → バージョンに応じて navigation-3-di.md または navigation-2-di.md
- Nav 2 から Nav 3 への移行 → navigation-migration.md
- Paging 3 のセットアップ、PagingSource、フィルター、LoadState、または変換 → paging.md
- Room と RemoteMediator を使ったオフラインファーストのページング → paging-offline.md
- Paging の MVI 連携、ページングのテスト、またはページングのアンチパターン → paging-mvi-testing.md
- Ktor クライアントのセットアップ、プラグイン、DTO、API サービス、またはリポジトリパターン → networking-ktor.md
- 認証(ベアラー)、WebSockets、または SSE → networking-ktor-auth.md
- ネットワーク層のアーキテクチャ、プラグインの構成、またはエラー処理の方針 → networking-ktor-architecture.md
- Hilt と Koin の選択 → まず dependency-injection.md を確認し、その後、選択したフレームワークのファイルを確認してください
- アクセシビリティ監査、セマンティクス、タッチターゲット、または WCAG のコントラスト → accessibility.md
- アニメーション API の選択(animate*AsState、Animatable、トランジション、AnimatedVisibility) → animations.md
- 共有要素トランジション、ジェスチャー駆動のアニメーション、Canvas、または graphicsLayer → animations-advanced.md
- コードレビューまたはアンチパターンの検出 → まず anti-patterns.md を確認し、必要に応じてドメイン固有のファイルも確認してください
- Kotlin の Swift への公開、SKIE、または Flow→AsyncSequence → ios-swift-interop.md
- ViewModel のパイプライン、状態のモデリング、ドメイン層、または機能間通信 → architecture.md
- MVI パイプライン、Event/State/Effect、onEvent パターン、または Effect の配信 → mvi.md
- MVVM パイプライン、名前付き関数を使う ViewModel、またはコールバックを直接使った UI の連携 → mvvm.md
- ファイル構成、命名規則、または規律ある画面アーキテクチャ → clean-code.md
- 3 つのフェーズ、状態プリミティブ、副作用、または修飾子 → compose-essentials.md
- M3 テーマ、ダイナミックカラー、M3 コンポーネント、またはアダプティブレイアウト → material-design.md
- AsyncImage、画像キャッシュ、SVG、または Coil 3 → image-loading.md
- LazyColumn、LazyRow、キー、グリッド、ページャー、またはスクロール状態 → lists-grids.md
- Nav 2 と Nav 3 の選択、または MVI のナビゲーション規則 → navigation.md
- 読み込み状態、スケルトン/シマー、またはインライン検証の UX → ui-ux.md
- Turbine、ViewModel のテスト、Macrobenchmark、または効率的なテストマトリクス → testing.md
- DataStore Preferences、Typed DataStore、または KMP DataStore → datastore.md
- Room のエンティティ、DAO、マイグレーション、リレーションシップ、または Room と MVI の連携 → room-database.md
- Ktor の
@Resourceルート、または型安全な API 定義 → networking-ktor.md § Type-Safe Resources - MockEngine、ネットワークのテスト、または Koin/Hilt によるネットワークの DI → networking-ktor-testing.md
- Koin CMP のセットアップ、Nav 3 と Koin の連携、またはスコープ付きモジュール → koin.md
- Hilt Android のセットアップ、@HiltViewModel、スコープ、または Hilt のテスト → hilt.md
- commonMain の共有、expect/actual、またはプラットフォームブリッジ → cross-platform.md
- CMP の Res クラス、修飾子、ローカライズ、または Android リソースとの連携 → resources.md
- AGP 9+、バージョンカタログ、コンベンションプラグイン、またはコンポジットビルド → gradle-build.md
- GitHub Actions による CI/CD、デスクトップアプリのパッケージング、署名、または公証 → ci-cd-distribution.md
検証
./scripts/validate.sh を実行して、スキルパッケージが agentskills.io の仕様 に準拠しているかを確認します。トークン数の上限、リンク切れ、ファイル構成、コンテンツの品質がチェックされます。コミットする前に、エラーを修正してください。