From rn-claude
Use when configuring EAS Build, Submit, or Update -- eas.json profiles, OTA updates, App Store/Play Store submission, GitHub Actions CI, EAS secrets.
How this skill is triggered — by the user, by Claude, or both
Slash command
/rn-claude:easThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Expo Application Services. Builds, submits, and updates your app.
Expo Application Services. Builds, submits, and updates your app.
eas.json{
"cli": { "version": ">= 12.0.0", "appVersionSource": "remote" },
"build": {
"base": {
"node": "22.0.0",
"env": {
"EXPO_PUBLIC_API_URL": "https://api.example.com"
}
},
"development": {
"extends": "base",
"developmentClient": true,
"distribution": "internal",
"env": { "EXPO_PUBLIC_API_URL": "https://dev-api.example.com" },
"ios": { "simulator": true }
},
"preview": {
"extends": "base",
"distribution": "internal",
"channel": "preview"
},
"production": {
"extends": "base",
"autoIncrement": true,
"channel": "production"
}
},
"submit": {
"production": {
"ios": { "appleId": "[email protected]", "ascAppId": "1234567890" },
"android": { "serviceAccountKeyPath": "./service-account.json", "track": "internal" }
}
}
}
# Development build (custom dev client)
bunx eas build --profile development --platform ios
bunx eas build --profile development --platform android
# Preview (internal distribution)
bunx eas build --profile preview --platform all
# Production
bunx eas build --profile production --platform all
# Local build (no EAS servers)
bunx eas build --profile development --platform ios --local
# Publish update to a channel
bunx eas update --channel preview --message "Fix login crash"
bunx eas update --channel production --message "v1.2.3 release"
# Check update status
bunx eas update:list
app.json update config:
{
"expo": {
"updates": {
"url": "https://u.expo.dev/YOUR-PROJECT-ID",
"enabled": true,
"fallbackToCacheTimeout": 0,
"checkAutomatically": "ON_LOAD"
},
"runtimeVersion": { "policy": "appVersion" }
}
}
Handle updates in root _layout.tsx:
import * as Updates from 'expo-updates'
import { useEffect } from 'react'
export default function RootLayout() {
// OTA update check is an SDK imperative call, not server data fetching --
// React Query doesn't apply here. This is the only acceptable useEffect+async pattern.
useEffect(() => {
async function checkUpdate() {
if (__DEV__) return
const update = await Updates.checkForUpdateAsync()
if (update.isAvailable) {
await Updates.fetchUpdateAsync()
await Updates.reloadAsync()
}
}
checkUpdate()
}, [])
// ...
}
# After a production build
bunx eas submit --platform ios --latest
bunx eas submit --platform android --latest
# Submit specific build
bunx eas submit --platform ios --id BUILD_ID
# Set secrets (never commit these)
bunx eas secret:create --scope project --name API_SECRET_KEY --value "..."
bunx eas secret:create --scope project --name SENTRY_DSN --value "..."
# List secrets
bunx eas secret:list
Access in build via eas.json env:
{ "build": { "production": { "env": { "SENTRY_DSN": "$SENTRY_DSN" } } } }
.github/workflows/eas-build.yml:
name: EAS Build
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22 }
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- uses: expo/expo-github-action@v8
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
- run: bunx eas build --profile production --platform all --non-interactive
.github/workflows/eas-update.yml:
name: EAS Update
on:
push:
branches: [main]
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- uses: expo/expo-github-action@v8
with: { eas-version: latest, token: '${{ secrets.EXPO_TOKEN }}' }
- run: bunx eas update --channel production --message "${{ github.event.head_commit.message }}" --non-interactive
eas.json must have development, preview, and production profileseas.json -- use EAS secrets or env varsservice-account.json or Apple credentials -- use EAS secretsconcurrency.cancel-in-progress: false in CI -- never cancel in-flight buildsruntimeVersion policy must be consistent across OTA updates and buildsnpx claudepluginhub shankulkarni/claude-plugin-marketplace --plugin rn-claudeCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.