Appleの設計ガイドライン(HIG)に沿ったスタイリング、意味のある色使い、ネイティブコントロール、SF Symbols(Appleのアイコン集)、メディア、アニメーション、視覚効果、グラデーション、ストレージ、レスポンシブレイアウトに対応した、美しいExpoの画面を構築できます。 ルーティングやナビゲーション機能が必要な場合は、expo-router スキルを使用してください。
Build beautiful, native-feeling Expo screens. Covers Apple HIG styling, semantic colors, native controls, SF Symbols, media, animations, visual effects, gradients, storage, and responsive layout. For routing and navigation, use the expo-router skill.
ルート(画面遷移経路)、リンク、スタック、タブ、モーダル(画面上に浮かぶ窓)、シート、ヘッダーについては、expo-router スキルを使用してください。
必要に応じて以下のリソースを参照してください:
references/
animations.md Reanimated: 表示/非表示アニメーション、レイアウト変化、スクロール連動、ジェスチャー
controls.md ネイティブiOS: スイッチ、スライダー、セグメントコントロール、日時選択、ピッカー
gradients.md CSSグラデーション(experimental_backgroundImage経由、新アーキテクチャ版のみ)
icons.md SF Symbols(expo-imageのsf:ソース経由)、名前、アニメーション、太さ
media.md カメラ、音声、動画、ファイル保存
storage.md SQLite、ローカルストレージ、セキュア保存
visual-effects.md ブラー(ぼかし)効果、リキッドグラス効果
webgpu-three.md 3Dグラフィックス、ゲーム、GPU処理(WebGPU・Three.js使用)
重要: カスタムビルドを作成する前に、必ずExpo Goで試してください。
ほとんどのExpoアプリは、ネイティブコードを追加せずにExpo Goで動作します。npx expo run:ios または npx expo run:android を実行する前に:
npx expo start を実行してExpo GoでQRコードをスキャンしてください以下を使用する場合のみ、npx expo run:ios/android または eas build が必要です:
modules/ にあるカスタムネイティブコード)@bacons/apple-targets 経由で使用)app.json で表現できないカスタムネイティブ設定Expo Goはすぐに使える多くの機能に対応しています:
expo-* パッケージ(カメラ、位置情報、通知など)判断に迷ったら、まずExpo Goを試してください。 カスタムビルドを作成すると複雑性が増し、開発の速度が落ち、Xcode・Android Studioのセットアップが必要になります。
comment-card.tsxexpo-av ではなく expo-audio を使用してくださいexpo-av ではなく expo-video を使用してくださいexpo-symbols や @expo/vector-icons ではなく、expo-image に source="sf:name" を指定してSF Symbolsを使用してくださいreact-native-safe-area-context を使用してくださいPlatform.OS ではなく process.env.EXPO_OS を使用してくださいReact.useContext ではなく React.use を使用してくださいimg などの組み込み要素ではなく、expo-image の Image コンポーネントを使用してくださいexpo-glass-effect を使用してくださいPlatformColor ではなく、expo-router の Color を使用してください(型安全性があり、ダーク・ライトモードに自動対応)@react-navigation/* から直接インポートしないでください — 代わりに expo-router/react-navigation を使用してください(@react-navigation/native、/core、/elements、/routers をカバー)<SafeAreaView> の代わりに <ScrollView contentInsetAdjustmentBehavior="automatic" /> を使用してください(安全領域を賢く処理)contentInsetAdjustmentBehavior="automatic" は FlatList・SectionList にも適用してくださいDimensions.get() ではなく 必ず useWindowDimensions を使用してください<Switch /> や @react-native-community/datetimepicker など、ハプティクス機能が組み込まれたビューを使用してくださいcontentInsetAdjustmentBehavior="automatic" が設定されたスクロールビューであるべきです<Text selectable /> を使用してくださいimg や div のような組み込み要素を使用しないでくださいApple Human Interface Guidelines に従ってください。
contentInsetAdjustmentBehavior="automatic" を使用して対応してくださいStyleSheet.create を使用するのではなくインラインスタイルを使用してください(スタイルを再利用する場合を除く){ borderCurve: 'continuous' } を使用してください(カプセル形を作る場合を除く)contentContainerStyle にパディングとギャップを設定してください(クリッピング を削減)expo-router の Color API を使用してネイティブなセマンティックカラー(意味を持つ色)を指定してください。これは PlatformColor の型安全なラッパーで、Color.ios.* を通じて iOS UIKit の色、Color.android.material.*(静的)または Color.android.dynamic.*(ユーザーの壁紙に適応)を通じて Android Material 3 の色を提供します。これらはデバイス上で解決され、ライト・ダークモードとアクセシビリティ設定に自動適応するため、ライト・ダーク用の16進数カラーテーブルや colors.web.ts ファイルを管理する必要がなくなります。
Color はプラットフォーム固有のため、各値を Platform.select で Web用の16進数フォールバック付きでラップしてください。パレットを theme/colors.ts で集約し、すべてのファイルから colors をインポートしてください:
// theme/colors.ts
import { Platform } from "react-native";
import { Color } from "expo-router";
export const colors = {
label: Platform.select({
ios: Color.ios.label,
android: Color.android.dynamic.onSurface,
default: "#000000",
})!,
secondaryLabel: Platform.select({
ios: Color.ios.secondaryLabel,
android: Color.android.dynamic.onSurfaceVariant,
default: "#3c3c43",
})!,
separator: Platform.select({
ios: Color.ios.separator,
android: Color.android.dynamic.outlineVariant,
default: "#c6c6c8",
})!,
systemBackground: Platform.select({
ios: Color.ios.systemBackground,
android: Color.android.dynamic.surface,
default: "#ffffff",
})!,
systemBlue: Platform.select({
ios: Color.ios.systemBlue,
android: Color.android.dynamic.primary,
default: "#007aff",
})!,
};
import { colors } from "@/theme/colors";
<View style={{ backgroundColor: colors.systemBackground }}>
<Text style={{ color: colors.label }}>Title</Text>
</View>;
useColorScheme() を呼び出してください(React Compiler がコンポーネントをメモ化する場合は必須)Color / PlatformColor 値を Reanimated スタイルに渡さないでください — そこでは静的な色を使用してください(references/animations.md を参照)Platform.select({...})! は string | OpaqueColorValue を返します。ほとんどの React Native スタイルプロップは ColorValue(string | OpaqueColorValue)を受け入れるため問題ありません。ただし、一部のサードパーティプロップは string のみを受け入れます(例: expo-image の tintColor)。必要に応じてキャストしてください: colors.label as string<Text/> 要素に selectable プロップを追加してください{ fontVariant: 'tabular-nums' } を使用して数字を揃えてくださいCSS の boxShadow スタイルプロップを使用してください。レガシーな React Native の影・昇降スタイルは決して使用しないでください。
<View style={{ boxShadow: "0 1px 2px rgba(0, 0, 0, 0.05)" }} />
内側の影(inset)もサポートされています。
For routes, links, stacks, tabs, modals, sheets, and headers, use the expo-router skill.
Consult these resources as needed:
references/
animations.md Reanimated: entering, exiting, layout, scroll-driven, gestures
controls.md Native iOS: Switch, Slider, SegmentedControl, DateTimePicker, Picker
gradients.md CSS gradients via experimental_backgroundImage (New Arch only)
icons.md SF Symbols via expo-image (sf: source), names, animations, weights
media.md Camera, audio, video, and file saving
storage.md SQLite, AsyncStorage, SecureStore
visual-effects.md Blur (expo-blur) and liquid glass (expo-glass-effect)
webgpu-three.md 3D graphics, games, GPU visualizations with WebGPU and Three.js
CRITICAL: Always try Expo Go first before creating custom builds.
Most Expo apps work in Expo Go without any custom native code. Before running npx expo run:ios or npx expo run:android:
npx expo start and scan the QR code with Expo GoYou need npx expo run:ios/android or eas build ONLY when using:
modules/)@bacons/apple-targets)app.jsonExpo Go supports a huge range of features out of the box:
expo-* packages (camera, location, notifications, etc.)If you're unsure, try Expo Go first. Creating custom builds adds complexity, slower iteration, and requires Xcode/Android Studio setup.
comment-card.tsxexpo-audio not expo-avexpo-video not expo-avexpo-image with source="sf:name" for SF Symbols, not expo-symbols or @expo/vector-iconsreact-native-safe-area-context not react-native SafeAreaViewprocess.env.EXPO_OS not Platform.OSReact.use not React.useContextexpo-image Image component instead of intrinsic element imgexpo-glass-effect for liquid glass backdropsColor from expo-router for native semantic colors, not raw PlatformColor (type-safe, auto-adapts to light/dark)@react-navigation/* directly — use expo-router/react-navigation instead (covers @react-navigation/native, /core, /elements, /routers)<ScrollView contentInsetAdjustmentBehavior="automatic" /> instead of <SafeAreaView> for smarter safe area insetscontentInsetAdjustmentBehavior="automatic" should be applied to FlatList and SectionList as welluseWindowDimensions over Dimensions.get() to measure screen size<Switch /> from React Native and @react-native-community/datetimepickercontentInsetAdjustmentBehavior="automatic" setScrollView to the page it should almost always be the first component inside the route component<Text selectable /> prop on text containing data that could be copiedFollow Apple Human Interface Guidelines.
contentInsetAdjustmentBehavior="automatic"{ borderCurve: 'continuous' } for rounded corners unless creating a capsule shapecontentContainerStyle padding and gap instead of padding on the ScrollView itself (reduces clipping)Use the Color API from expo-router for native semantic colors. It is a type-safe wrapper over PlatformColor that exposes iOS UIKit colors through Color.ios.* and Android Material 3 colors through Color.android.material.* (static) or Color.android.dynamic.* (adapts to the user's wallpaper on Android 12+). These resolve on-device and automatically adapt to light/dark mode and accessibility settings, so you no longer maintain separate light/dark hex tables or a colors.web.ts file.
Color is platform-specific, so wrap each value in Platform.select with a default hex fallback for web. Centralize the palette in theme/colors.ts and import colors everywhere:
// theme/colors.ts
import { Platform } from "react-native";
import { Color } from "expo-router";
export const colors = {
label: Platform.select({
ios: Color.ios.label,
android: Color.android.dynamic.onSurface,
default: "#000000",
})!,
secondaryLabel: Platform.select({
ios: Color.ios.secondaryLabel,
android: Color.android.dynamic.onSurfaceVariant,
default: "#3c3c43",
})!,
separator: Platform.select({
ios: Color.ios.separator,
android: Color.android.dynamic.outlineVariant,
default: "#c6c6c8",
})!,
systemBackground: Platform.select({
ios: Color.ios.systemBackground,
android: Color.android.dynamic.surface,
default: "#ffffff",
})!,
systemBlue: Platform.select({
ios: Color.ios.systemBlue,
android: Color.android.dynamic.primary,
default: "#007aff",
})!,
};
import { colors } from "@/theme/colors";
<View style={{ backgroundColor: colors.systemBackground }}>
<Text style={{ color: colors.label }}>Title</Text>
</View>;
useColorScheme() inside any component that renders them so it re-renders when the theme flips (required when React Compiler memoizes the component).Color / PlatformColor values into Reanimated styles — use static colors there (see references/animations.md).Platform.select({...})! returns string | OpaqueColorValue. Most React Native style props accept ColorValue (string | OpaqueColorValue) so this works fine. But some third-party props only accept string (e.g. tintColor on expo-image). Cast when needed: colors.label as string.selectable prop to every <Text/> element displaying important data or error messages{ fontVariant: 'tabular-nums' } for alignmentUse CSS boxShadow style prop. NEVER use legacy React Native shadow or elevation styles.
<View style={{ boxShadow: "0 1px 2px rgba(0, 0, 0, 0.05)" }} />
'inset' shadows are supported.
原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。