Skip to content
expo-build-deploy logo

Expo Build & Deploy (iOS)

expo-build-deploy

Building and deploying Expo React Native apps to iOS. Use when configuring EAS Build, submitting to TestFlight, App Store deployment, managing certificates, or troubleshooting build issues.

SKILL.md

Full skill instructions

Expo Build & Deploy (iOS)

EAS Build Setup

Initial configuration

# Install EAS CLI
npm install -g eas-cli

# Login to Expo account
eas login

# Initialize EAS in project
eas build:configure

This creates eas.json:

{
  "cli": {
    "version": ">= 5.0.0"
  },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "ios": {
        "simulator": true
      }
    },
    "preview": {
      "distribution": "internal"
    },
    "production": {}
  },
  "submit": {
    "production": {}
  }
}

app.json iOS configuration

{
  "expo": {
    "name": "MyApp",
    "slug": "myapp",
    "version": "1.0.0",
    "scheme": "myapp",
    "ios": {
      "bundleIdentifier": "com.yourcompany.myapp",
      "buildNumber": "1",
      "supportsTablet": false,
      "infoPlist": {
        "NSCameraUsageDescription": "Take photos for your profile",
        "NSLocationWhenInUseUsageDescription": "Find locations near you"
      }
    }
  }
}

Build Types

Development build (for development)

# For simulator
eas build --profile development --platform ios

# For physical device
eas build --profile development --platform ios --local

Use with npx expo start --dev-client

Preview build (internal testing)

eas build --profile preview --platform ios

Distributes via ad-hoc provisioning. Testers install via link.

Production build (App Store)

eas build --profile production --platform ios

Credentials Management

EAS manages credentials automatically, but you can control them:

# View current credentials
eas credentials

# Let EAS manage everything (recommended)
# Just run build, it handles certificates

# Use existing credentials
eas credentials --platform ios
# Select "Use existing" and provide paths

Manual credential setup (if needed)

  1. Create App ID in Apple Developer Portal
  2. Create Distribution Certificate
  3. Create Provisioning Profile
  4. Configure in eas.json:
{
  "build": {
    "production": {
      "ios": {
        "credentialsSource": "local"
      }
    }
  }
}

Environment Variables

In eas.json

{
  "build": {
    "production": {
      "env": {
        "API_URL": "https://api.yourapp.com"
      }
    },
    "preview": {
      "env": {
        "API_URL": "https://staging-api.yourapp.com"
      }
    }
  }
}

Secrets (sensitive values)

# Set secret
eas secret:create --name API_KEY --value "sk_live_xxx" --scope project

# List secrets
eas secret:list

# Use in app.json
{
  "extra": {
    "apiKey": process.env.API_KEY
  }
}

Access in code:

import Constants from 'expo-constants';

const apiKey = Constants.expoConfig?.extra?.apiKey;

TestFlight Deployment

Configure submit profile

{
  "submit": {
    "production": {
      "ios": {
        "appleId": "[email protected]",
        "ascAppId": "1234567890",
        "appleTeamId": "XXXXXXXXXX"
      }
    }
  }
}

Get ascAppId from App Store Connect URL: https://appstoreconnect.apple.com/​apps/​1234567890

Submit to TestFlight

# Build and submit in one command
eas build --profile production --platform ios --auto-submit

# Or submit existing build
eas submit --platform ios --latest

# Submit specific build
eas submit --platform ios --id <build-id>

App Store Connect setup (first time)

  1. Create app in App Store Connect
  2. Fill in app information
  3. Set up TestFlight:
    • Add internal testers (immediate access)
    • Create external testing group (requires review)

App Store Submission

Pre-submission checklist

  • App icons (1024x1024 for App Store)
  • Screenshots for required device sizes
  • Privacy policy URL
  • App description and keywords
  • Age rating questionnaire
  • Export compliance (encryption)

Submit for review

  1. Build with production profile
  2. Submit to App Store Connect
  3. In App Store Connect:
    • Select build for submission
    • Complete app information
    • Submit for review
# Automated submission
eas submit --platform ios --latest

Over-the-Air Updates

For JS/​asset-only changes (no native code changes):

# Publish update
eas update --branch production --message "Bug fix for login"

# Preview before publishing
eas update --branch preview --message "Testing new feature"

Configure update channels

{
  "build": {
    "production": {
      "channel": "production"
    },
    "preview": {
      "channel": "preview"
    }
  }
}

Check for updates in app

import * as Updates from 'expo-updates';

async function checkForUpdates() {
  if (__DEV__) return; // Skip in development
  
  try {
    const update = await Updates.checkForUpdateAsync();
    if (update.isAvailable) {
      await Updates.fetchUpdateAsync();
      await Updates.reloadAsync();
    }
  } catch (error) {
    console.log('Update check failed:', error);
  }
}

Version Management

Increment version for new features

{
  "expo": {
    "version": "1.1.0"  // Shown to users
  }
}

Increment buildNumber for each build

{
  "expo": {
    "ios": {
      "buildNumber": "2"  // Must increase for each upload
    }
  }
}

Automate with EAS

{
  "build": {
    "production": {
      "ios": {
        "autoIncrement": "buildNumber"
      }
    }
  }
}

Local Builds

Build on your machine instead of EAS servers:

# Requires Xcode installed
eas build --platform ios --local

Useful for:

  • Faster iteration during debugging
  • Inspecting build output
  • Offline builds

Troubleshooting

Build fails with signing error

# Reset credentials and let EAS regenerate
eas credentials --platform ios
# Select "Remove" then rebuild

"Missing compliance" warning

Add to app.json:

{
  "expo": {
    "ios": {
      "infoPlist": {
        "ITSAppUsesNonExemptEncryption": false
      }
    }
  }
}

Build succeeds but app crashes

# Check native logs
eas build:view <build-id>

# Download and inspect build
eas build:download <build-id>

TestFlight build stuck in processing

  • Usually takes 10-30 minutes
  • Check App Store Connect for status
  • Ensure buildNumber is unique

OTA update not applied

  • Verify channel matches
  • Check Updates.checkForUpdateAsync() is called
  • Ensure not in development mode
  • Updates only apply on next cold start

Common Commands Reference

# Build
eas build --platform ios --profile production
eas build --platform ios --profile preview
eas build --platform ios --local

# Submit
eas submit --platform ios --latest
eas submit --platform ios --id <build-id>

# Updates
eas update --branch production --message "Fix"
eas update:list

# Credentials
eas credentials --platform ios
eas credentials:configure

# View builds
eas build:list
eas build:view <build-id>
eas build:cancel <build-id>

# Secrets
eas secret:create --name KEY --value "xxx"
eas secret:list

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View