コンテンツにスキップ

03. Spec Kitでアプリの画面骨格とルーティングを生成する

実機での初期起動が確認できたら、いよいよアプリの中身を作っていきます。

最初に行うべきは、細かなボタンや色をいじることではなく、「アプリ全体の画面骨格(スケルトン)とルーティング(画面遷移構造)」を一気に組み上げることです。

そしてここが、Spec Kit のワークフローを初めて一周させる場面になります。仕様を書き、計画を立て、タスクに割り、実装する。この4ステップを実際に体験しておくと、以降の機能追加はすべて同じリズムで進められます。


  1. Expo Routerにおける画面構成の基本ルール(TabsとStack)
  2. /speckit.specify で最初の機能仕様を書く
  3. /speckit.clarify と /speckit.plan で実装計画を固める
  4. /speckit.tasks でタスクに分解し、/speckit.implement で実装する
  5. 生成されたコードの確認(appディレクトリ構造と実装例)
  6. 動的ルーティングとモーダル画面の追加設計
  7. 実機でのルーティング動作テストチェックリスト
  8. まとめと次のステップ

1. Expo Routerにおける画面構成の基本ルール(TabsとStack)

Section titled “1. Expo Routerにおける画面構成の基本ルール(TabsとStack)”

Expo Routerでは、フォルダ構造とファイル名がそのままアプリの画面遷移に対応します。

一般的なモバイルアプリでは、画面下部に常駐する タブナビゲーション(Tabs) と、詳細画面や設定画面へ重なるように遷移する スタックナビゲーション(Stack) を組み合わせて設計します。

app/
├── _layout.tsx # 全体のルートレイアウト(Stack)
├── (tabs)/ # 下部タブバーで切り替えるグループ
│ ├── _layout.tsx # タブバーのアイコン・ラベル・色設定
│ ├── index.tsx # タブ1: 今日の習慣(ダッシュボード)
│ ├── history.tsx # タブ2: 達成カレンダー(履歴)
│ └── settings.tsx # タブ3: 設定
└── modal.tsx # モーダル表示する画面(下からスライドイン)
  • _layout.tsx: そのフォルダ配下の画面共通の枠組み(ヘッダーやタブバー、認証チェックなど)を定義するファイル。
  • () 括弧付きのフォルダ: 「グループ化」を意味し、URLやルートパスには影響を与えずにレイアウトを適用できる。

この構造を、これからSpec Kitに「仕様」として書かせます。


2. /speckit.specify で最初の機能仕様を書く

Section titled “2. /speckit.specify で最初の機能仕様を書く”

/speckit.specify は、1つの機能について「何を作るのか」を書くコマンドです。ここではまだ技術的な話をしません。「どんな画面があって、ユーザーが何をできるか」だけを書きます。

AIエージェントのチャット欄で、次のように入力します。

/speckit.specify
アプリの画面骨格とナビゲーション構造を用意する。
プロジェクトルートの `SPEC.md` と `DESIGN.md` を読み込み、そこに定義された
画面構成に基づいて仕様を書いてください。
### この機能でやること
- 画面下部に3つのタブ(「今日」「履歴」「設定」)を持つナビゲーションを用意する。
- 「今日」タブは、その日の習慣一覧を表示するメイン画面。
- 「履歴」タブは、過去の達成記録を振り返る画面。
- 「設定」タブは、アプリ情報やデータ初期化を置く画面。
- 習慣を新規追加するための画面は、下からせり上がるモーダルとして表示する。
- 各画面は、この段階では見出しとプレースホルダーのみを表示すればよい。
### この機能でやらないこと
- 習慣データの保存・読み込み(次の機能で実装する)
- カードやボタンのデザイン実装(次の機能で実装する)
- ログイン・認証画面(SPEC.md の Out of Scope)

実行すると、Spec Kitが specs/001-app-navigation-skeleton/spec.md(名前は内容から自動で決まります)を作成します。


3. /speckit.clarify と /speckit.plan で実装計画を固める

Section titled “3. /speckit.clarify と /speckit.plan で実装計画を固める”

仕様に決めきれていない点があると、AIは実装時に勝手に判断します。/speckit.clarify は、その「決まっていない点」をAIの側から質問させるコマンドです。

/speckit.clarify

「タブの並び順は?」「モーダルはどのタブからでも開けるのか?」といった質問が返ってくるので、答えると spec.md に反映されます。

仕様が固まったら、どう作るかを決めます。ここで初めて技術スタックの話が出てきます。

/speckit.plan
Expo Router のファイルベースルーティングで実装します。
- `app/(tabs)/_layout.tsx` にタブバーを定義し、アイコンは `@expo/vector-icons`
の Ionicons を使う。
- タブのアクティブ色・非アクティブ色・境界線は、`DESIGN.md` のカラートークンを
そのまま使うこと(Primary: #10B981 / TextSecondary: #6B7280 / Border: #E5E7EB)。
- モーダルは `app/_layout.tsx` のルートStackに `presentation: 'modal'` で登録する。
- `create-expo-app` のテンプレートが生成したサンプル画面
(`explore.tsx` など)は削除する。
- 各画面はセーフエリアを考慮し、`react-native-safe-area-context` の
`SafeAreaView` でラップすること。

specs/001-.../plan.md が生成されます。ここには「どのファイルを作り、どのライブラリを使うか」が書かれています。この段階なら、方針の間違いはファイルを1行直すだけで修正できます。


4. /speckit.tasks でタスクに分解し、/speckit.implement で実装する

Section titled “4. /speckit.tasks でタスクに分解し、/speckit.implement で実装する”
/speckit.tasks

specs/001-.../tasks.md に、チェックボックス付きの作業リストが生成されます。

- [ ] T001 `app/(tabs)/_layout.tsx` を作成し、3タブのTabsを定義する
- [ ] T002 `app/(tabs)/index.tsx` を「今日」画面のプレースホルダーとして作成
- [ ] T003 `app/(tabs)/history.tsx` を「履歴」画面のプレースホルダーとして作成
- [ ] T004 `app/(tabs)/settings.tsx` を「設定」画面のプレースホルダーとして作成
- [ ] T005 `app/_layout.tsx` にモーダル用の Stack.Screen を登録する
- [ ] T006 `app/modal.tsx` を作成する
- [ ] T007 サンプルファイル(explore.tsx 等)を削除する
- [ ] T008 `npx tsc --noEmit` が通ることを確認する

タスクの粒度が大きすぎる、あるいは順番がおかしいと感じたら、この時点で直します。

/speckit.implement

AIエージェントが tasks.md を上から順に実行し、終わったタスクにチェックを入れていきます。途中で会話が切れても、tasks.md を見れば続きから再開できます。


5. 生成されたコードの確認(appディレクトリ構造と実装例)

Section titled “5. 生成されたコードの確認(appディレクトリ構造と実装例)”

実装が終わったら、生成された app/(tabs)/_layout.tsx を確認してみましょう。

import { Tabs } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';
export default function TabLayout() {
return (
<Tabs
screenOptions={{
tabBarActiveTintColor: '#10B981', // DESIGN.mdのPrimaryカラー
tabBarInactiveTintColor: '#6B7280', // DESIGN.mdのTextSecondary
tabBarStyle: {
backgroundColor: '#FFFFFF',
borderTopColor: '#E5E7EB', // DESIGN.mdのBorder
paddingTop: 8,
},
headerShown: true,
headerStyle: { backgroundColor: '#FFFFFF' },
headerTitleStyle: { fontWeight: '700', color: '#111827' }, // DESIGN.mdのTextPrimary
}}
>
<Tabs.Screen
name="index"
options={{
title: '今日',
headerTitle: 'HabitFlow',
tabBarIcon: ({ color, size }) => (
<Ionicons name="checkbox-outline" size={size} color={color} />
),
}}
/>
<Tabs.Screen
name="history"
options={{
title: '履歴',
headerTitle: '達成カレンダー',
tabBarIcon: ({ color, size }) => (
<Ionicons name="calendar-outline" size={size} color={color} />
),
}}
/>
<Tabs.Screen
name="settings"
options={{
title: '設定',
headerTitle: '設定',
tabBarIcon: ({ color, size }) => (
<Ionicons name="settings-outline" size={size} color={color} />
),
}}
/>
</Tabs>
);
}

カラーコードが DESIGN.md のトークンと一致していることを確認してください。ここがズレていたら、憲法(.specify/memory/constitution.md)のデザイン遵守の記述が弱い可能性があります。


6. 動的ルーティングとモーダル画面の追加設計

Section titled “6. 動的ルーティングとモーダル画面の追加設計”

習慣の編集画面や新規作成画面を「下からニュッとせり上がるモーダル」として表示したい場合、Expo Routerなら app/_layout.tsx に数行追加するだけで実現できます。

app/_layout.tsx
import { Stack } from 'expo-router';
export default function RootLayout() {
return (
<Stack>
{/* タブグループはヘッダー非表示で埋め込む */}
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
{/* モーダル画面の定義 */}
<Stack.Screen
name="modal"
options={{
presentation: 'modal',
headerTitle: '習慣の追加',
}}
/>
</Stack>
);
}

このように、タブとモーダルの階層をAIに指示するだけで、ネイティブアプリ特有の洗練された画面遷移が数行で組み上がります。


7. 実機でのルーティング動作テストチェックリスト

Section titled “7. 実機でのルーティング動作テストチェックリスト”

スマホ実機(Expo Go)を見てみましょう。ホットリロードによって即座に画面が更新されているはずです。

  • 画面下部に「今日」「履歴」「設定」の3つのタブが表示されているか
  • 各タブをタップしたときに、ヘッダータイトルとコンテンツがスムーズに切り替わるか
  • アイコンとアクティブ時のカラー(Primaryカラー: #10B981)が正しく反映されているか
  • iPhoneのノッチ(画面上部の切り欠き)やホームバーと重ならず、セーフエリアが確保されているか
  • ターミナルにルーティング関連の警告(Warning)が出ていないか
  • specs/001-.../tasks.md のチェックボックスがすべて埋まっているか

アプリの「器(骨格)」ができたことで、次はこの器の中に具体的なUIパーツを流し込んでいきます。


Spec Kit のワークフローを一周させ、画面骨格とルーティングを固めました。仕様 → 計画 → タスク → 実装という順序に慣れてしまえば、あとは同じことを機能の数だけ繰り返すだけです。

次の記事では、リデザイン編(Phase03)でGoogle Stitchを使って定義した美しいUIパーツ(カード、進捗バー、ボタンなど)を、2周目のSpec Kitサイクルで実装する「04. Spec KitでStitchのデザインをUIコンポーネントに実装する」に進みましょう。