jpskill.com
🛠️ 開発・MCP コミュニティ

expo

Expoを使ってReact Nativeアプリを開発、配布、更新し、Expo RouterによるファイルベースルーティングやEAS Buildによるビルド設定、OTAアップデート、カメラや位置情報などのSDK連携を支援するSkill。

📜 元の英語説明(参考)

Build, deploy, and update React Native apps with Expo. Covers file-based routing with Expo Router (stacks, tabs, drawers, deep linking), EAS Build and Submit, over-the-air updates, and 50+ SDK modules for camera, location, notifications. Use when setting up Expo, adding navigation, configuring builds, or integrating native device APIs. Trigger words: expo, expo router, eas build, react native expo, file-based routing mobile, deep linking.

🇯🇵 日本人クリエイター向け解説

一言でいうと

Expoを使ってReact Nativeアプリを開発、配布、更新し、Expo RouterによるファイルベースルーティングやEAS Buildによるビルド設定、OTAアップデート、カメラや位置情報などのSDK連携を支援するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o expo.zip https://jpskill.com/download/14881.zip && unzip -o expo.zip && rm expo.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/14881.zip -OutFile "$d\expo.zip"; Expand-Archive "$d\expo.zip" -DestinationPath $d -Force; ri "$d\expo.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して expo.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → expo フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Expo

概要

Expo は React Native のための開発プラットフォームであり、ファイルベースルーティング (Expo Router)、クラウドビルド (EAS Build)、ストアへの提出 (EAS Submit)、OTA (Over-the-Air) アップデート (EAS Update)、およびネイティブデバイス API のための 50 以上の SDK モジュールを提供します。Xcode や Android Studio を管理することなく、1 つのコードベースから iOS、Android、および Web アプリをリリースできます。

手順

セットアップ

npx create-expo-app@latest my-app --template tabs
cd my-app && npx expo start

ファイルベースルーティング (Expo Router)

app/ にファイルをドロップすると、画面が作成されます。フォルダ構造がナビゲーション階層を定義します。

app/
├── _layout.tsx          # ルートレイアウト (すべての画面をラップ)
├── index.tsx            # / (ホーム画面)
├── about.tsx            # /about
├── (tabs)/              # タブナビゲーショングループ
│   ├── _layout.tsx      # タブバーの設定
│   ├── index.tsx      # 最初のタブ
│   ├── explore.tsx      # 2 番目のタブ
│   └── profile.tsx      # 3 番目のタブ
├── settings/
│   ├── _layout.tsx      # 設定のためのスタックレイアウト
│   ├── index.tsx      # /settings
│   └── account.tsx      # /settings/account
├── post/
│   └── [slug].tsx       # /post/my-first-post (動的ルート)
└── +not-found.tsx       # 404 画面

ルートレイアウト

// app/_layout.tsx
import { Stack } from "expo-router";

export default function RootLayout() {
  return (
    <Stack>
      <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
      <Stack.Screen name="settings" options={{ title: "Settings" }} />
      <Stack.Screen name="modal" options={{ presentation: "modal" }} />
    </Stack>
  );
}

タブナビゲーション

// app/(tabs)/_layout.tsx
import { Tabs } from "expo-router";
import { Ionicons } from "@expo/vector-icons";

export default function TabLayout() {
  return (
    <Tabs screenOptions={{ tabBarActiveTintColor: "#007AFF" }}>
      <Tabs.Screen name="index" options={{
        title: "Home",
        tabBarIcon: ({ color }) => <Ionicons name="home" size={24} color={color} />,
      }} />
      <Tabs.Screen name="explore" options={{
        title: "Explore",
        tabBarIcon: ({ color }) => <Ionicons name="compass" size={24} color={color} />,
      }} />
      <Tabs.Screen name="profile" options={{
        title: "Profile",
        tabBarIcon: ({ color }) => <Ionicons name="person" size={24} color={color} />,
      }} />
    </Tabs>
  );
}

ナビゲーションと動的ルート

import { Link, router, useLocalSearchParams } from "expo-router";

// 宣言的: <Link href="/post/hello-world">My Post</Link>
// プログラム的: router.push("/settings/account")

// app/post/[slug].tsx — 動的ルート
export default function PostScreen() {
  const { slug } = useLocalSearchParams<{ slug: string }>();
  return <Text>{slug}</Text>;
}

ディープリンク (自動)

すべてのルートは自動的に URL を取得します。app.json でスキームを設定します。

{ "expo": { "scheme": "myapp" } }
  • myapp:// -> ホーム画面
  • myapp://post/hello-world -> 投稿画面
  • https://myapp.com/post/hello-world -> 同じ画面 (ユニバーサルリンク)

Expo SDK モジュール

// Camera
import { CameraView, useCameraPermissions } from "expo-camera";
const [permission, requestPermission] = useCameraPermissions();
const photo = await cameraRef.current?.takePictureAsync();

// Push Notifications
import * as Notifications from "expo-notifications";
const token = await Notifications.getExpoPushTokenAsync({ projectId: "your-id" });

// Secure Storage
import * as SecureStore from "expo-secure-store";
await SecureStore.setItemAsync("token", "jwt-abc123");

EAS Build, Submit, および Update

npm install -g eas-cli
eas build:configure
eas build --platform ios          # クラウドビルド -> .ipa
eas build --platform android      # クラウドビルド -> .aab
eas submit --platform ios         # App Store Connect
eas submit --platform android     # Google Play Console
eas update --branch production --message "Bug fix"  # OTA アップデート

例 1: タブ、スタック、およびモーダルを備えたソーシャルアプリ

ユーザープロンプト: 「ソーシャルアプリのナビゲーションを設定します。フィード/検索/プロフィールのためのタブ、投稿詳細のためのスタック、および投稿作成のためのモーダル。」

エージェントは app/(tabs)/_layout.tsx にタブレイアウトを作成し、投稿詳細のためのネストされたスタックルート、および presentation: "modal" を持つモーダルルートを作成します。ディープリンクはすべてのルートで自動的に機能します。

例 2: OTA アップデートによる緊急バグ修正のリリース

ユーザープロンプト: 「アプリストアのレビューなしで、緊急修正を本番環境にプッシュします。」

エージェントは JavaScript コードを修正し、eas update --channel production を実行し、アップデートのフィンガープリントがネイティブコードの変更がないことを確認し、問題が発生した場合にロールバックが利用可能な状態でロールアウトを監視します。

ガイドライン

  • ファイル = ルートapp/about.tsx/about になります
  • ナビゲーションコンテナのための _layout.tsx (Stack, Tabs, Drawer)
  • ルートグループのための (group) — URL に影響を与えずに整理します
  • 動的ルートのための [param]useLocalSearchParams 経由でアクセスします
  • ディープリンクは自動 — すべてのルートに URL があります
  • より良いキャッシュと最新のフォーマットサポートのために Image よりも expo-image を使用してください
  • シークレットは expo-secure-store に保存し、決して AsyncStorage に保存しないでください
  • マネージドワークフローを維持するために、イジェクトする代わりに config plugins を使用してください
  • カスタムネイティブモジュールには開発ビルドを使用してください (Expo Go はそれらを実行できません)
  • ローカルの Xcode/Android Studio なしで再現可能なクロスプラットフォームビルドのために EAS Build を使用してください
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Expo

Overview

Expo is a development platform for React Native providing file-based routing (Expo Router), cloud builds (EAS Build), store submissions (EAS Submit), over-the-air updates (EAS Update), and 50+ SDK modules for native device APIs. Ship iOS, Android, and web apps from one codebase without managing Xcode or Android Studio.

Instructions

Setup

npx create-expo-app@latest my-app --template tabs
cd my-app && npx expo start

File-Based Routing (Expo Router)

Drop a file in app/, get a screen. Folder structure defines navigation hierarchy.

app/
├── _layout.tsx          # Root layout (wraps all screens)
├── index.tsx            # / (home screen)
├── about.tsx            # /about
├── (tabs)/              # Tab navigation group
│   ├── _layout.tsx      # Tab bar configuration
│   ├── index.tsx        # First tab
│   ├── explore.tsx      # Second tab
│   └── profile.tsx      # Third tab
├── settings/
│   ├── _layout.tsx      # Stack layout for settings
│   ├── index.tsx        # /settings
│   └── account.tsx      # /settings/account
├── post/
│   └── [slug].tsx       # /post/my-first-post (dynamic route)
└── +not-found.tsx       # 404 screen

Root Layout

// app/_layout.tsx
import { Stack } from "expo-router";

export default function RootLayout() {
  return (
    <Stack>
      <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
      <Stack.Screen name="settings" options={{ title: "Settings" }} />
      <Stack.Screen name="modal" options={{ presentation: "modal" }} />
    </Stack>
  );
}

Tab Navigation

// app/(tabs)/_layout.tsx
import { Tabs } from "expo-router";
import { Ionicons } from "@expo/vector-icons";

export default function TabLayout() {
  return (
    <Tabs screenOptions={{ tabBarActiveTintColor: "#007AFF" }}>
      <Tabs.Screen name="index" options={{
        title: "Home",
        tabBarIcon: ({ color }) => <Ionicons name="home" size={24} color={color} />,
      }} />
      <Tabs.Screen name="explore" options={{
        title: "Explore",
        tabBarIcon: ({ color }) => <Ionicons name="compass" size={24} color={color} />,
      }} />
      <Tabs.Screen name="profile" options={{
        title: "Profile",
        tabBarIcon: ({ color }) => <Ionicons name="person" size={24} color={color} />,
      }} />
    </Tabs>
  );
}

Navigation and Dynamic Routes

import { Link, router, useLocalSearchParams } from "expo-router";

// Declarative: <Link href="/post/hello-world">My Post</Link>
// Programmatic: router.push("/settings/account")

// app/post/[slug].tsx — Dynamic route
export default function PostScreen() {
  const { slug } = useLocalSearchParams<{ slug: string }>();
  return <Text>{slug}</Text>;
}

Deep Linking (Automatic)

Every route gets a URL automatically. Configure the scheme in app.json:

{ "expo": { "scheme": "myapp" } }
  • myapp:// -> Home screen
  • myapp://post/hello-world -> Post screen
  • https://myapp.com/post/hello-world -> Same screen (universal links)

Expo SDK Modules

// Camera
import { CameraView, useCameraPermissions } from "expo-camera";
const [permission, requestPermission] = useCameraPermissions();
const photo = await cameraRef.current?.takePictureAsync();

// Push Notifications
import * as Notifications from "expo-notifications";
const token = await Notifications.getExpoPushTokenAsync({ projectId: "your-id" });

// Secure Storage
import * as SecureStore from "expo-secure-store";
await SecureStore.setItemAsync("token", "jwt-abc123");

EAS Build, Submit, and Update

npm install -g eas-cli
eas build:configure
eas build --platform ios          # Cloud build -> .ipa
eas build --platform android      # Cloud build -> .aab
eas submit --platform ios         # App Store Connect
eas submit --platform android     # Google Play Console
eas update --branch production --message "Bug fix"  # OTA update

Examples

Example 1: Social app with tabs, stacks, and modals

User prompt: "Set up navigation for a social app — tabs for feed/search/profile, stack for post details, and modal for creating posts."

The agent creates a tab layout in app/(tabs)/_layout.tsx, nested stack routes for post details, and a modal route with presentation: "modal". Deep linking works automatically for every route.

Example 2: Ship an urgent bug fix via OTA update

User prompt: "Push an urgent fix to production without app store review."

The agent fixes the JavaScript code, runs eas update --channel production, verifies the update fingerprint ensures no native code changes, and monitors rollout with rollback available if issues arise.

Guidelines

  • File = routeapp/about.tsx becomes /about
  • _layout.tsx for navigation containers (Stack, Tabs, Drawer)
  • (group) for route groups — organize without affecting URL
  • [param] for dynamic routes — access via useLocalSearchParams
  • Deep linking is automatic — every route has a URL
  • Use expo-image over Image for better caching and modern format support
  • Store secrets in expo-secure-store, never AsyncStorage
  • Use config plugins instead of ejecting to keep managed workflow
  • Use development builds for custom native modules (Expo Go cannot run them)
  • Use EAS Build for reproducible cross-platform builds without local Xcode/Android Studio