Courses/Grit Mobile/Build & App Store
Course 5 of 5~30 min10 challenges

Build & App Store

Your app works in development — now it's time to ship it. In this course, you will learn to build production binaries with EAS, distribute through TestFlight and the Play Store, prepare your store listing, and push updates without going through app review.


Development vs Production Build

During development, you run the app through Expo Go — a shell app that loads your JavaScript code over the network. This is fast for iteration but not distributable. For the App Store, you need a standalone binary — a real .ipa (iOS) or .apk/.aab (Android) file.

Development Build: Running your app through Expo Go or a development client. The JavaScript code is loaded over the network from your computer. Fast to iterate but cannot be submitted to the App Store or Play Store.
Production Build: A standalone binary (.ipa for iOS, .aab for Android) that contains your app's JavaScript bundle and all native dependencies. This is what you submit to the App Store or Play Store. Users download and install it like any other app.
1

Challenge: Understand the Difference

Explain in your own words why you cannot submit an Expo Go-based app to the App Store. What is the difference between loading JavaScript over the network and bundling it into a standalone binary?

EAS Build

EAS (Expo Application Services): A cloud build service by Expo. EAS builds your app on Expo's servers so you don't need Xcode (macOS only) or Android Studio installed locally. You run a single command, and EAS handles compilation, signing, and packaging.

Install the EAS CLI and configure your project:

# Install EAS CLI globally
npm install -g eas-cli

# Log in to your Expo account
eas login

# Initialize EAS in your project
cd apps/expo && eas build:configure

This creates an eas.json file with build profiles:

{
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal"
    },
    "preview": {
      "distribution": "internal"
    },
    "production": {}
  }
}

To build for a specific platform:

# Build for iOS
eas build --platform ios

# Build for Android
eas build --platform android

# Build for both
eas build --platform all
Use the preview profile for internal testing (distributes via QR code or link) and production for store submissions.
2

Challenge: Set Up EAS

Install eas-cli with npm install -g eas-cli. Run eas whoami to check if you're logged in. If not, run eas login to create an account and log in.

iOS Build

Building for iOS requires an Apple Developer account ($99/year). Apple requires all iOS apps to be signed with certificates and provisioning profiles. EAS handles this automatically — it creates and manages certificates for you.

Requirements for an iOS build:

  • Apple Developer account ($99/year)
  • App ID registered in Apple Developer portal (EAS does this automatically)
  • Signing certificates and provisioning profiles (EAS manages these)
  • Bundle identifier (e.g., com.yourcompany.fitness)
TestFlight: Apple's official beta testing platform. After building your iOS app, you upload it to TestFlight through App Store Connect. You can then invite up to 10,000 testers who install the app via the TestFlight app. This lets you test with real users before submitting to the public App Store.
# Build for iOS production
eas build --platform ios --profile production

# Submit to App Store Connect (TestFlight)
eas submit --platform ios
You do not need a Mac to build for iOS with EAS. The build happens on Expo's cloud servers (which run macOS). You only need a Mac if you want to build locally.
3

Challenge: iOS Requirements

What do you need to build for iOS? List all the requirements. Which ones does EAS handle automatically, and which ones do you need to set up yourself?

Android Build

Android builds require a signing keystore — a file that proves you are the developer of the app. EAS can generate one for you automatically on your first build.

APK (Android Package): An installable file you can share directly with anyone. They open the file on their Android phone and install it. No Play Store required. Good for testing and internal distribution.
AAB (Android App Bundle): An optimized format required by the Google Play Store. Google processes the AAB and generates optimized APKs for each device configuration (screen size, CPU architecture). This results in smaller downloads for users.
# Build an APK (for direct sharing/testing)
eas build --platform android --profile preview

# Build an AAB (for Play Store submission)
eas build --platform android --profile production

# Submit to Google Play Store
eas submit --platform android

For the Play Store, you need a Google Play Developer account ($25 one-time fee). Unlike Apple, the Android build process works on any operating system.

4

Challenge: APK vs AAB

What's the difference between an APK and an AAB? When would you use each? If you wanted to send a test build to a friend who has an Android phone, which format would you use?

App Store Assets

Both the Apple App Store and Google Play Store require specific assets before you can publish your app:

AssetRequirement
App Icon1024x1024 PNG, no transparency (iOS), 512x512 PNG (Android)
ScreenshotsVarious sizes for different devices (iPhone, iPad, Android phones/tablets)
DescriptionShort description (~80 chars) + full description (~4000 chars)
KeywordsUp to 100 characters of comma-separated keywords (iOS only)
Privacy PolicyA URL to your privacy policy (required by both stores)
CategoryPrimary and optional secondary category (e.g., Health & Fitness)
Use a tool like Hotpot Icon Resizer to generate all required icon sizes from a single 1024x1024 source image.
5

Challenge: Write a Store Description

Write a 3-sentence App Store description for your fitness app. It should explain what the app does, who it's for, and what makes it useful. Keep it clear and compelling.

6

Challenge: Plan Your Screenshots

List 5 screenshots you would take for your app's store listing. For each, describe the screen shown and what feature it highlights. The first screenshot is the most important — it's what users see when browsing.

OTA Updates

OTA (Over-The-Air) Updates: Pushing JavaScript updates directly to users' devices without going through the App Store or Play Store review process. When the user opens the app, it checks for updates and downloads the new JavaScript bundle in the background. The next time they open the app, they see the updated version.

OTA updates are one of the biggest advantages of React Native with Expo. App Store review can take 1-3 days. With OTA, your fix reaches users in minutes.

# Push an OTA update to all users on the production channel
eas update --branch production --message "Fix workout timer bug"

# Push to a preview channel for testing first
eas update --branch preview --message "Test new feature"

There are important limitations to OTA updates:

  • Can update: JavaScript code, images, fonts — anything in the JS bundle
  • Cannot update: Native code, new native modules, app icon, splash screen
If you add a new native dependency (e.g., a camera library), you need a full build and store submission. OTA only works for JavaScript-level changes.
7

Challenge: OTA vs Full Build

Explain why OTA updates are useful. Give two examples of changes that can be shipped via OTA and two examples that require a full build and store submission.

Deploying the API

Your mobile app needs a live API to talk to. During development, the app connects tolocalhost. In production, it connects to your deployed API server.

Deploy the Go API using grit deploy (covered in the Grit Web Deploy course) to a VPS with a domain and HTTPS. Then update the mobile app's API URL:

// lib/api.ts
const API_URL = __DEV__
  ? "http://localhost:8080"       // Development
  : "https://api.fitness.com"     // Production

The __DEV__ variable is true in development and false in production builds. This lets you switch between local and remote APIs automatically.

Always use HTTPS for your production API. Mobile platforms are increasingly strict about insecure connections — iOS blocks HTTP by default, and Android 9+ does the same.
8

Challenge: Update the API URL

If your API is deployed at api.fitness.com, what changes would you make in the mobile app's API client? Where is the base URL configured? How do you handle the difference between development and production?

Summary

Here's what you learned in this course:

  • EAS Build compiles your app in the cloud — no Xcode or Android Studio needed
  • iOS requires an Apple Developer account; Android requires a Google Play Developer account
  • TestFlight distributes iOS betas; APKs distribute Android test builds directly
  • OTA updates ship JS changes instantly — no store review required
  • Deploy the Go API to a VPS with HTTPS for production mobile apps
9

Challenge: Write a Launch Checklist

Write a complete launch checklist for your fitness app with these sections: (1) API deployment, (2) iOS build with TestFlight testing, (3) Android build with APK for internal testing, (4) App Store and Play Store listing assets, (5) OTA update strategy for post-launch fixes.

10

Challenge: Ship It

If you have developer accounts, run a real build with eas build --platform all. If not, run eas build --platform android --profile preview (free, no account required for APK) and install the APK on an Android device or emulator. Take a screenshot of your app running as a standalone build.