一键导入
expo-tv-config
Expo TV configuration: app.json plugins, prebuild settings, platform-specific config for react-native-tvos
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Expo TV configuration: app.json plugins, prebuild settings, platform-specific config for react-native-tvos
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Template repo file structure: where screens, navigation, theme, data, and platform entries live in the monorepo
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
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 | expo-tv-config |
| description | Expo TV configuration: app.json plugins, prebuild settings, platform-specific config for react-native-tvos |
| applies_to | ["phase_clone","phase_prebuild"] |
| load_when | configuring `app.json`, running prebuild, or builds fail with config errors |
The Expo plugin
@react-native-tvos/config-tvis the single switch that makes an Expo app build for TV. Get this wrong and you ship a phone app to a TV launcher. Get it right and most platform-specific config is automatic.
EXPO_TV=1
This must be set when:
expo prebuildexpo run:android or expo run:ios for a TV buildFor harness-driven Android work, prefer expo prebuild followed by the Gradle
wrapper and android run. Treat expo run:android as a manual compatibility
command because Android CLI should own deployment and launch when available.
Without it, the plugin no-ops and you get a mobile build. The expo_prebuild tool always sets it; if a user invokes prebuild manually, the symptom is silent — the build succeeds but the app is wrong.
A handy .envrc (direnv) or shell alias avoids forgetting:
export EXPO_TV=1
[
"@react-native-tvos/config-tv",
{
"isTV": true,
"androidTVBanner": "./assets/icon-400x240.png",
"showVerboseWarnings": false
}
]
isTV: true — required. Drives Android leanback config and tvOS deployment target.androidTVBanner — path to the 400×240 banner. Required for Android TV / Fire TV. See firetv-leanback.md.showVerboseWarnings — verbose prebuild output. Useful when debugging.On Android:
<intent-filter> with LEANBACK_LAUNCHER to the main activity<uses-feature android:name="android.software.leanback" android:required="false" /><uses-feature android:name="android.hardware.touchscreen" android:required="false" />On iOS:
This is why you don't edit native files directly. Anything the plugin does, the plugin owns. Manual edits get clobbered on the next prebuild.
EXPO_TV=1 npx expo prebuild --clean
--clean regenerates ios/ and android/ from scratch. This is what you want in CI and in the harness — reproducible builds. Without --clean, prebuild merges into existing native files and merge conflicts are silent and weird.
app.json (any field).expo SDK or react-native-tvos.packages/shared-ui or apps/expo-multi-tv/src/. JS bundles don't require regeneration.Unnecessary prebuilds cost 60–120s and risk wiping any custom native edits (which the agent shouldn't have made, but).
The template ships with Expo SDK 51 and react-native-tvos@0.74-stable (or whatever the README states — verify on clone). Compatibility table:
| Expo SDK | react-native-tvos version | Notes |
|---|---|---|
| 51 | 0.74-stable | Template default |
| 52 | 0.76-stable | Newer; verify all deps |
| 54 | 0.81-stable | Latest at time of writing; newest TV features |
If the user requests a newer SDK, bump deliberately:
expo and react-native (the alias to react-native-tvos) in both apps.expo-router, expo-font, etc.).yarn install.expo prebuild --clean.The agent should not silently bump. SDK changes are visible diffs.
// eas.json
{
"build": {
"preview-tv-android": {
"extends": "preview",
"env": { "EXPO_TV": "1" },
"android": { "buildType": "apk" }
},
"preview-tv-ios": {
"extends": "preview",
"env": { "EXPO_TV": "1" },
"ios": { "simulator": false }
}
}
}
env.EXPO_TV is the equivalent of the shell variable. Without it on EAS, you get a mobile build out of the cloud — same symptom as locally.
| Symptom | Cause | Fix |
|---|---|---|
| Mobile-looking app on a TV target | EXPO_TV not set during prebuild | Re-run with the env var, --clean |
| Prebuild fails: "android resource not found" | Banner path wrong in app.json | Fix path; rerun prebuild |
| Prebuild succeeds but app crashes on launch | SDK / react-native-tvos version mismatch | Align versions per the table above |
expo run:ios builds a phone app | Xcode scheme is the phone target | Open ios/, switch scheme to the -tvOS variant, or use expo run:ios --device <TV-simulator> |
| "Plugin not found: @react-native-tvos/config-tv" | Plugin not installed in the app's workspace | yarn workspace expo-multi-tv add @react-native-tvos/config-tv |
| Banner appears stretched | Wrong dimensions, not exactly 400×240 | Regenerate at correct size |
Plugin updates → require prebuild. Runtime JS updates → don't.
If a plugin update is included in a normal yarn and the agent forgets to prebuild afterward, the build will succeed but the change won't take effect on native. Always prebuild after a plugin change.
EXPO_TV inside the JS code. It's a build-time variable. Setting it at runtime does nothing.ios/ or android/ directly to "fix" something. Prebuild will erase it. If a fix is needed, write or extend a config plugin.--clean during prebuild because "it's faster". It is faster. It's also the source of half of the "works on my machine" bugs.expo run:ios when an iPhone simulator is open. The build may target the phone. Specify the TV device or close the phone simulator first.