Expo Deployment
OpenAIOfficialCreated by Expo TeamDistributed by OpenAI
- Skill
- Tool integration
- Cloud and DevOps
- MIT
- Low risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a comprehensive guide for using Expo Application Services (EAS) to build, manage, and deploy Expo applications. It covers the configuration of build profiles, automated submission to the Apple App Store and Google Play Store, and web hosting deployment. The skill also includes instructions for managing app metadata, handling credentials, and integrating CI/CD workflows for automated release pipelines.
What it does
- Configures build profiles for iOS, Android, and web platforms
- Automates the submission of application binaries to app stores
- Manages App Store metadata and store configuration
- Provides commands for TestFlight beta distribution
- Enables web hosting deployment and PR preview generation
- Supports CI/CD integration for automated build and release workflows
When to use it
- When preparing an Expo application for release to mobile app stores
- When setting up automated deployment pipelines for mobile or web
- When managing App Store metadata and store presence
- When distributing beta builds to testers via TestFlight
- When deploying web versions of an Expo project
Advantages
- Centralizes build and submission processes
- Reduces manual effort for store metadata management
- Supports automated versioning and build tracking
- Facilitates consistent deployment workflows across platforms
Usage examples
- “How do I build and submit my iOS app to the App Store?”
- The agent provides the command 'npx eas-cli build -p ios --profile production --submit' and explains the necessary credential configuration.
- “How can I automate my release process?”
- The agent provides a sample YAML workflow configuration for CI/CD to automate building and submitting apps upon pushing to the main branch.
- “How do I update my App Store metadata?”
- The agent explains how to use 'eas metadata:pull' to generate a config file and 'eas metadata:push' to update store information.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/openai/expo-deployment/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip expo-deployment.zip -d .agents/skills
Documentation by Expo Team
Deployment
This skill covers deploying Expo applications across all platforms using EAS (Expo Application Services).
References
Consult these resources as needed:
./references/workflows.md -- CI/CD workflows for automated deployments and PR previews
./references/testflight.md -- Submitting iOS builds to TestFlight for beta testing
./references/app-store-metadata.md -- Managing App Store metadata and ASO optimization
./references/play-store.md -- Submitting Android builds to Google Play Store
./references/ios-app-store.md -- iOS App Store submission and review process
Quick Start
Install EAS CLI
npm install -g eas-cli
eas loginInitialize EAS
npx eas-cli@latest initThis creates eas.json with build profiles.
Build Commands
Production Builds
# iOS App Store build
npx eas-cli@latest build -p ios --profile production
# Android Play Store build
npx eas-cli@latest build -p android --profile production
# Both platforms
npx eas-cli@latest build --profile productionSubmit to Stores
# iOS: Build and submit to App Store Connect
npx eas-cli@latest build -p ios --profile production --submit
# Android: Build and submit to Play Store
npx eas-cli@latest build -p android --profile production --submit
# Shortcut for iOS TestFlight
npx testflightWeb Deployment
Deploy web apps using EAS Hosting:
# Deploy to production
npx expo export -p web
npx eas-cli@latest deploy --prod
# Deploy PR preview
npx eas-cli@latest deployEAS Configuration
Standard eas.json for production deployments:
{
"cli": {
"version": ">= 16.0.1",
"appVersionSource": "remote"
},
"build": {
"production": {
"autoIncrement": true,
"ios": {
"resourceClass": "m-medium"
}
},
"development": {
"developmentClient": true,
"distribution": "internal"
}
},
"submit": {
"production": {
"ios": {
"appleId": "[email protected]",
"ascAppId": "1234567890"
},
"android": {
"serviceAccountKeyPath": "./google-service-account.json",
"track": "internal"
}
}
}
}Platform-Specific Guides
iOS
Use
npx testflightfor quick TestFlight submissionsConfigure Apple credentials via
eas credentialsSee ./reference/testflight.md for credential setup
See ./reference/ios-app-store.md for App Store submission
Android
Set up Google Play Console service account
Configure tracks: internal → closed → open → production
See ./reference/play-store.md for detailed setup
Web
EAS Hosting provides preview URLs for PRs
Production deploys to your custom domain
See ./reference/workflows.md for CI/CD automation
Automated Deployments
Use EAS Workflows for CI/CD:
# .eas/workflows/release.yml
name: Release
on:
push:
branches: [main]
jobs:
build-ios:
type: build
params:
platform: ios
profile: production
submit-ios:
type: submit
needs: [build-ios]
params:
platform: ios
profile: productionSee ./reference/workflows.md for more workflow examples.
Version Management
EAS manages version numbers automatically with appVersionSource: "remote":
# Check current versions
eas build:version:get
# Manually set version
eas build:version:set -p ios --build-number 42Monitoring
# List recent builds
eas build:list
# Check build status
eas build:view
# View submission status
eas submit:listFiles
- ATTRIBUTION.mdAdded by AutoGineer820 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md3.6 KiB
- agents/openai.yaml368 B
- references/app-store-metadata.md13.0 KiB
- references/ios-app-store.md6.9 KiB
- references/play-store.md5.1 KiB
- references/testflight.md1.6 KiB
- references/workflows.md3.0 KiB
references/app-store-metadata.md
App Store Metadata
Manage App Store metadata and optimize for ASO using EAS Metadata.
What is EAS Metadata?
EAS Metadata automates App Store presence management from the command line using a store.config.json file instead of manually filling forms in App Store Connect. It includes built-in validation to catch common rejection pitfalls.
Current Status: Preview, Apple App Store only.
Getting Started
Pull Existing Metadata
If your app is already published, pull current metadata:
eas metadata:pullThis creates store.config.json with your current App Store configuration.
Push Metadata Updates
After editing your config, push changes:
eas metadata:pushImportant: You must submit a binary via eas submit before pushing metadata for new apps.
Configuration File
Create store.config.json at your project root:
{
"configVersion": 0,
"apple": {
"copyright": "2025 Your Company",
"categories": ["UTILITIES", "PRODUCTIVITY"],
"info": {
"en-US": {
"title": "App Name",
"subtitle": "Your compelling tagline",
"description": "Full app description...",
"keywords": ["keyword1", "keyword2", "keyword3"],
"releaseNotes": "What's new in this version...",
"promoText": "Limited time offer!",
"privacyPolicyUrl": "https://example.com/privacy",
"supportUrl": "https://example.com/support",
"marketingUrl": "https://example.com"
}
},
"advisory": {
"alcoholTobaccoOrDrugUseOrReferences": "NONE",
"gamblingSimulated": "NONE",
"medicalOrTreatmentInformation": "NONE",
"profanityOrCrudeHumor": "NONE",
"sexualContentGraphicAndNudity": "NONE",
"sexualContentOrNudity": "NONE",
"horrorOrFearThemes": "NONE",
"matureOrSuggestiveThemes": "NONE",
"violenceCartoonOrFantasy": "NONE",
"violenceRealistic": "NONE",
"violenceRealisticProlongedGraphicOrSadistic": "NONE",
"contests": "NONE",
"gambling": false,
"unrestrictedWebAccess": false,
"seventeenPlus": false
},
"release": {
"automaticRelease": true,
"phasedRelease": true
},
"review": {
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"phone": "+1 555-123-4567",
"notes": "Demo account: [email protected] / password123"
}
}
}App Store Optimization (ASO)
Title Optimization (30 characters max)
The title is the most important ranking factor. Include your brand name and 1-2 strongest keywords.
{
"title": "Budgetly - Money Tracker"
}Best Practices:
Brand name first for recognition
Include highest-volume keyword
Avoid generic words like "app" or "the"
Title keywords boost rankings by ~10%
Subtitle Optimization (30 characters max)
The subtitle appears below your title in search results. Use it for your unique value proposition.
{
"subtitle": "Smart Expense & Budget Planner"
}Best Practices:
Don't duplicate keywords from title (Apple counts each word once)
Highlight your main differentiator
Include secondary high-value keywords
Focus on benefits, not features
Keywords Field (100 characters max)
Hidden from users but crucial for discoverability. Use comma-separated keywords without spaces after commas.
{
"keywords": [
"finance,budget,expense,money,tracker,savings,bills,income,spending,wallet,personal,weekly,monthly"
]
}Best Practices:
Use all 100 characters
Separate with commas only (no spaces)
No duplicates from title/subtitle
Include singular forms (Apple handles plurals)
Add synonyms and alternate spellings
Include competitor brand names (carefully)
Use digits instead of spelled numbers ("5" not "five")
Skip articles and prepositions
Description Optimization
The iOS description is NOT indexed for search but critical for conversion. Focus on convincing users to download.
{
"description": "Take control of your finances with Budgetly, the intuitive money management app trusted by over 1 million users.\n\nKEY FEATURES:\n• Smart budget tracking - Set limits and watch your progress\n• Expense categorization - Know exactly where your money goes\n• Bill reminders - Never miss a payment\n• Beautiful charts - Visualize your financial health\n• Bank sync - Connect 10,000+ institutions\n• Cloud backup - Your data, always safe\n\nWHY BUDGETLY?\nUnlike complex spreadsheets or basic calculators, Budgetly learns your spending habits and provides personalized insights. Our users save an average of $300/month within 3 months.\n\nPRIVACY FIRST\nYour financial data is encrypted end-to-end. We never sell your information.\n\nDownload Budgetly today and start your journey to financial freedom!"
}Best Practices:
Front-load the first 3 lines (visible before "more")
Use bullet points for features
Include social proof (user counts, ratings, awards)
Add a clear call-to-action
Mention privacy/security for sensitive apps
Update with each release
Release Notes
Shown to existing users deciding whether to update.
{
"releaseNotes": "Version 2.5 brings exciting improvements:\n\n• NEW: Dark mode support\n• NEW: Widget for home screen\n• IMPROVED: 50% faster sync\n• FIXED: Notification timing issues\n\nLove Budgetly? Please leave a review!"
}Promo Text (170 characters max)
Appears above description; can be updated without new binary. Great for time-sensitive promotions.
{
"promoText": "🎉 New Year Special: Premium features free for 30 days! Start 2025 with better finances."
}Categories
Primary category is most important for browsing and rankings.
{
"categories": ["FINANCE", "PRODUCTIVITY"]
}Available Categories:
BOOKS, BUSINESS, DEVELOPER_TOOLS, EDUCATION
ENTERTAINMENT, FINANCE, FOOD_AND_DRINK
GAMES (with subcategories), GRAPHICS_AND_DESIGN
HEALTH_AND_FITNESS, KIDS (age-gated)
LIFESTYLE, MAGAZINES_AND_NEWSPAPERS
MEDICAL, MUSIC, NAVIGATION, NEWS
PHOTO_AND_VIDEO, PRODUCTIVITY, REFERENCE
SHOPPING, SOCIAL_NETWORKING, SPORTS
STICKERS (with subcategories), TRAVEL
UTILITIES, WEATHER
Localization
Localize metadata for each target market. Keywords should be researched per locale—direct translations often miss regional search terms.
{
"info": {
"en-US": {
"title": "Budgetly - Money Tracker",
"subtitle": "Smart Expense Planner",
"keywords": ["budget,finance,money,expense,tracker"]
},
"es-ES": {
"title": "Budgetly - Control de Gastos",
"subtitle": "Planificador de Presupuesto",
"keywords": ["presupuesto,finanzas,dinero,gastos,ahorro"]
},
"ja": {
"title": "Budgetly - 家計簿アプリ",
"subtitle": "簡単支出管理",
"keywords": ["家計簿,支出,予算,節約,お金"]
},
"de-DE": {
"title": "Budgetly - Haushaltsbuch",
"subtitle": "Ausgaben Verwalten",
"keywords": ["budget,finanzen,geld,ausgaben,sparen"]
}
}
}Supported Locales:
ar-SA, ca, cs, da, de-DE, el, en-AU, en-CA, en-GB, en-US, es-ES, es-MX, fi, fr-CA, fr-FR, he, hi, hr, hu, id, it, ja, ko, ms, nl-NL, no, pl, pt-BR, pt-PT, ro, ru, sk, sv, th, tr, uk, vi, zh-Hans, zh-Hant
Dynamic Configuration
Use JavaScript for dynamic values like copyright year or fetched translations.
Basic Dynamic Config
// store.config.js
const baseConfig = require("./store.config.json");
const year = new Date().getFullYear();
module.exports = {
...baseConfig,
apple: {
...baseConfig.apple,
copyright: `${year} Your Company, Inc.`,
},
};Async Configuration (External Localization)
// store.config.js
module.exports = async () => {
const baseConfig = require("./store.config.json");
// Fetch translations from CMS/localization service
const translations = await fetch(
"https://api.example.com/app-store-copy"
).then((r) => r.json());
return {
...baseConfig,
apple: {
...baseConfig.apple,
info: translations,
},
};
};Environment-Based Config
// store.config.js
const baseConfig = require("./store.config.json");
const isProduction = process.env.EAS_BUILD_PROFILE === "production";
module.exports = {
...baseConfig,
apple: {
...baseConfig.apple,
info: {
"en-US": {
...baseConfig.apple.info["en-US"],
promoText: isProduction
? "Download now and get started!"
: "[BETA] Help us test new features!",
},
},
},
};Update eas.json to use JS config:
{
"cli": {
"metadataPath": "./store.config.js"
}
}Age Rating (Advisory)
Answer content questions honestly to get an appropriate age rating.
Content Descriptors:
NONE- Content not presentINFREQUENT_OR_MILD- Occasional mild contentFREQUENT_OR_INTENSE- Regular or strong content
{
"advisory": {
"alcoholTobaccoOrDrugUseOrReferences": "NONE",
"contests": "NONE",
"gambling": false,
"gamblingSimulated": "NONE",
"horrorOrFearThemes": "NONE",
"matureOrSuggestiveThemes": "NONE",
"medicalOrTreatmentInformation": "NONE",
"profanityOrCrudeHumor": "NONE",
"sexualContentGraphicAndNudity": "NONE",
"sexualContentOrNudity": "NONE",
"unrestrictedWebAccess": false,
"violenceCartoonOrFantasy": "NONE",
"violenceRealistic": "NONE",
"violenceRealisticProlongedGraphicOrSadistic": "NONE",
"seventeenPlus": false,
"kidsAgeBand": "NINE_TO_ELEVEN"
}
}Kids Age Bands: FIVE_AND_UNDER, SIX_TO_EIGHT, NINE_TO_ELEVEN
Release Strategy
Control how your app rolls out to users.
{
"release": {
"automaticRelease": true,
"phasedRelease": true
}
}Options:
automaticRelease: true- Release immediately upon approvalautomaticRelease: false- Manual release after approvalautomaticRelease: "2025-02-01T10:00:00Z"- Schedule release (RFC 3339)phasedRelease: true- 7-day gradual rollout (1%, 2%, 5%, 10%, 20%, 50%, 100%)
Review Information
Provide contact info and test credentials for the App Review team.
{
"review": {
"firstName": "Jane",
"lastName": "Smith",
"email": "[email protected]",
"phone": "+1 (555) 123-4567",
"demoUsername": "[email protected]",
"demoPassword": "ReviewDemo2025!",
"notes": "To test premium features:\n1. Log in with demo credentials\n2. Navigate to Settings > Subscription\n3. Tap 'Restore Purchase' - sandbox purchase will be restored\n\nFor location features, allow location access when prompted."
}
}ASO Checklist
Before Each Release
[ ] Update keywords based on performance data
[ ] Refresh description with new features
[ ] Write compelling release notes
[ ] Update promo text if running campaigns
[ ] Verify all URLs are valid
Monthly ASO Tasks
[ ] Analyze keyword rankings
[ ] Research competitor keywords
[ ] Check conversion rates in App Analytics
[ ] Review user feedback for keyword ideas
[ ] A/B test screenshots in App Store Connect
Keyword Research Tips
Brainstorm features - List all app capabilities
Mine reviews - Find words users actually use
Analyze competitors - Check their titles/subtitles
Use long-tail keywords - Less competition, higher intent
Consider misspellings - Common typos can drive traffic
Track seasonality - Some keywords peak at certain times
Metrics to Monitor
Impressions - How often your app appears in search
Product Page Views - Users who tap to learn more
Conversion Rate - Views → Downloads
Keyword Rankings - Position for target keywords
Category Ranking - Position in your categories
VS Code Integration
Install the Expo Tools extension for:
Auto-complete for all schema properties
Inline validation and warnings
Quick fixes for common issues
Common Issues
"Binary not found"
Push a binary with eas submit before pushing metadata.
"Invalid keywords"
Check total length is ≤100 characters
Remove spaces after commas
Remove duplicate words
"Description too long"
Description maximum is 4000 characters.
Pull doesn't update JS config
eas metadata:pull creates a JSON file; import it into your JS config.
CI/CD Integration
Automate metadata updates in your deployment pipeline:
# .eas/workflows/release.yml
jobs:
submit-and-metadata:
steps:
- name: Submit to App Store
run: eas submit -p ios --latest
- name: Push Metadata
run: eas metadata:pushTips
Update metadata every 4-6 weeks for optimal ASO
70% of App Store visitors use search to find apps
Apps with 4+ star ratings get featured more often
Localized apps see 128% more downloads per country
First 3 lines of description are most critical (shown before "more")
Use all 100 keyword characters—every character counts
Requirements and compatibility
Written for: OpenAI Codex
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Node.js
Security
What our scanner noticed· Low risk
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Expo Team
- Publisher
- OpenAI (Official)
- Distributed by
- OpenAI
- Source
- openai/plugins · plugins/expo/skills/expo-deployment · commit d420d13
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from plugins/expo/LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Expo Team or OpenAI.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download expo-deployment.zip