ワンクリックで
rn-template-anatomy
Template repo file structure: where screens, navigation, theme, data, and platform entries live in the monorepo
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Template repo file structure: where screens, navigation, theme, data, and platform entries live in the monorepo
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Android TV build and D-pad QA using Android CLI first, with bounded Gradle and ADB fallbacks
Expo Application Services cloud build configuration for TV app APK and IPA generation
Expo TV configuration: app.json plugins, prebuild settings, platform-specific config for react-native-tvos
Fire TV leanback manifest configuration: banner icons, LEANBACK_LAUNCHER intent filter, TV-specific Android settings
Gradle build commands: assembleDebug, assembleRelease, APK output paths, and emulator installation
Fire TV Vega OS (Kepler) build system: npx kepler build, Vega app structure, platform-specific components
| name | rn-template-anatomy |
| description | Template repo file structure: where screens, navigation, theme, data, and platform entries live in the monorepo |
| applies_to | ["phase_clone","phase_brand","phase_manifest","phase_screens","phase_build"] |
| load_when | any time the agent reads or writes project files |
The base template is
AmazonAppDev/react-native-multi-tv-app-sample. Knowing where things live is half the job. Editing the wrong file is most of the failures.
react-native-multi-tv-app-sample/
├── apps/
│ ├── expo-multi-tv/ # Universal app: Android TV, Apple TV, Fire TV (FOS), Web
│ └── vega/ # Fire TV Vega OS only (separate SDK)
├── packages/
│ └── shared-ui/ # All shared components, screens, hooks, theme, data
├── package.json # Yarn workspaces root
└── tsconfig.base.json # Shared TS config
apps/expo-multi-tv/ — anything that runs on Android TV, Apple TV, Fire TV FOS, or Web. Edit when:
app.json: name, slug, bundle ID, banner)apps/vega/ — Fire TV Vega OS only. Edit when:
firetv-vega@amazon-devices/* packagesDo not try to merge the two apps. They share UI via packages/shared-ui and that's the boundary. If a feature won't work on Vega, gate it; don't fork the shared package.
packages/shared-ui/ is the heartThis is where ~80% of edits go. Layout:
packages/shared-ui/
├── components/ # Reusable UI: Drawer, Grid, Hero, Tile, Player, etc.
├── screens/ # Composed screens: Home, Detail, Player, Settings
├── navigation/ # Drawer/route config
├── hooks/ # Data hooks (manifest consumption)
├── theme/ # Tokens, theme provider
├── data/ # Static data, manifest goes here
└── remote-control/ # Per-platform remote handlers
Metro picks the right file by extension. This is how the template handles platform splits without if (Platform.OS === ...) everywhere.
| Extension | Resolved when |
|---|---|
Foo.android.ts | Android TV + Fire TV FOS builds |
Foo.ios.ts | Apple TV build |
Foo.kepler.ts | Vega OS build (Kepler is the Vega runtime) |
Foo.web.ts | Web build |
Foo.ts | Fallback for any platform without a specific file |
Foo.ts.Foo.ts (default) + Foo.kepler.ts (override).| Asset | Location | Notes |
|---|---|---|
| App icon | apps/expo-multi-tv/assets/icon.png | 1024×1024 |
| Splash | apps/expo-multi-tv/assets/splash.png | 1920×1080 minimum for TV |
| Android TV banner | apps/expo-multi-tv/assets/icon-400x240.png | Exact 400×240, required for leanback |
| Shared images | packages/shared-ui/assets/ | Component-local images |
| Vega assets | apps/vega/assets/ | Vega-specific |
# Install root + all workspaces
yarn
# Add a dep to a specific workspace
yarn workspace expo-multi-tv add <pkg>
yarn workspace @multi-tv/shared-ui add <pkg>
# Run a script in a workspace
yarn workspace expo-multi-tv run android
Anti-pattern: running npm install in a sub-app directory. It breaks the workspace symlinks. Always use yarn at the root, or yarn workspace ....
Anti-pattern: adding react or react-native to packages/shared-ui/devDependencies. With nmHoistingLimits: workspaces, this installs a physical copy at packages/shared-ui/node_modules/react/ which the web bundler resolves as a separate React instance, crashing the app with "Invalid hook call." Use only @types/react for typechecking in shared-ui. The runtime react is resolved via Metro's nodeModulesPaths (pointing to the expo app's node_modules) on all platforms.
| You want to add… | Put it here |
|---|---|
| A new component | packages/shared-ui/components/<Name>/ |
| A new screen | packages/shared-ui/screens/<Name>/ + register in navigation/ |
| Content manifest | packages/shared-ui/data/content.json (overwrites existing) |
| A new data hook | packages/shared-ui/hooks/use<Name>.ts |
| Theme tokens | packages/shared-ui/theme/tokens.ts |
| Vega-only feature | apps/vega/src/<feature>/ |
apps/*/ios/ and apps/*/android/ — native projects, regenerated by expo prebuild. Manual edits get blown away. If you need a change, do it via Expo config plugins.app.json plugins array — order matters; @react-native-tvos/config-tv must come before plugins that modify the manifest.tsconfig.base.json — changing path aliases breaks Metro resolution. If you must, also update Metro config.yarn runs cleanly from the root.yarn workspace expo-multi-tv tsc --noEmit passes.If any of those fail before you start, fix that first. Don't pile new changes on a broken tree.