Skip to content

YosefHayim/launch-store

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

309 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Launch — build, sign & ship to the App Store and Google Play

Open-source, self-hosted alternative to Expo EAS — build, sign, configure your stores, and ship Expo / React Native apps to the App Store & Google Play from one typed launch.config.ts — your machine, your keys. No per-build bill.

npm version npm downloads CI status MIT license Node version TypeScript types included

211 App Store Connect & Google Play API operations Full create / read / update / delete coverage across the store APIs 2008 tests passing

English · 简体中文 · 日本語 · 한국어 · Español · Português · Français · Deutsch · Русский

📦 Releases & changelog

Shipping an app is more than a build: signing setup, App Store Connect / Play Console config, in-app purchases, subscriptions, capabilities, and listing metadata — and EAS builds and submits, then leaves all of that to Apple's and Google's portals and a handful of tools. Launch is the only release tool that makes the whole path — store config included — declarative: from one typed launch.config.ts it provisions your signing, reconciles your App Store Connect and Google Play catalog (products, prices, offers, capabilities, and listing), generates the native project, builds and signs the binary, reports the real per-device download size, stores the artifact, and uploads to the testing track — on hardware you own, with keys that stay in your local keychain. iOS signing needs a Mac; if you don't have one, Launch builds on a cloud Mac in your own AWS EC2 Mac account or hands off to Expo EAS — see Building without a Mac.

New here? Run launch demo for a 60-second simulated walkthrough of the whole pipeline — no setup, no build, no account needed. It also auto-plays the first time you run launch.

Launch feature map — setup, store configuration, build, release, re-sign, notifications, distribution, team management, and reports

Why Launch

The build was never the hard part — the release around it is. Launch owns that whole surface, locally and open source:

  • The whole release, one workflow. Signing, store products, build, size-check, upload, and OTA updates come from one launch.config.ts and a handful of commands — not a dozen dashboards and CI snippets.
  • Store setup as code. launch sync reconciles in-app purchases, subscriptions, pricing, and capabilities onto App Store Connect from one typed launch.config.ts; a dozen more commands cover Game Center, Wallet, App Clips, in-app events, A/B experiments, territories, and the whole Google Play catalog — plus launch metadata for the listing. These are the parts EAS leaves you to click by hand.
  • $0 compute, unlimited builds. EAS bills by build, caps the free tier behind a 45-minute timeout, and runs $19–$199/mo plus overage on paid plans. Launch builds on your own machine — no meter, no queue, no timeout.
  • Your keys stay local. Your distribution certificate, App Store Connect API key, and Android upload key stay in your OS keychain; Launch only ever sends a CSR to Apple. (Building without a Mac is the one exception — see below.)
  • No lock-in, ever. MIT-licensed, built on fastlane, Gradle, and the platforms' own APIs, with pluggable storage/credentials/build/submit providers. Nothing proprietary to migrate off later.
  • It teaches as it runs. Add --explain to any command — or run launch demo — to expand each step (CSR, provisioning profile, TestFlight, Play track, subscription group) into plain English.

What Launch is — and is not

Launch is an end-to-end release tool: it owns the whole path from source to store — build, code-sign, size-check, store-config-as-code, upload, public release, and over-the-air updates — for both iOS and Android, on hardware you own.

Launch is not just an App Store Connect SDK or an ASC MCP server. Those wrap a slice of Apple's API; Launch drives the entire release across Apple and Google, with signing, building, and OTA updates that an API wrapper doesn't touch. If you want a self-hosted Expo EAS — not just an API client — that's Launch.

Features

Set up & verify
  1. Config in one step. launch init detects your app(s) — including an apps/* monorepo — and writes a commented launch.config.ts plus a starter .env.example, touching no credentials or native code.
  2. Onboard a live app. launch adopt imports an already-shipping app's App Store Connect setup — products, capabilities, listing, signing — back into launch.config.ts.
  3. Keys in your keychain. launch creds set-key validates your AuthKey_*.p8 against Apple and vaults it in your OS keychain; creds use/rename/remove switch between teams.
  4. APNs push-key vault. launch creds push-key safe-keeps a download-once APNs auth key and re-exports it on demand — Apple exposes no API to recreate one.
  5. Secrets, not plaintext .env. launch secret set/list/rm stores build secrets in your OS keychain, scoped per app/profile, and injects them into the build env.
  6. One-command doctor. launch doctor --fix detects the iOS/Android toolchain, installs the missing brew-able tools behind a single consent, and flags store-side blockers.
  7. Hands-off setup. launch setup scaffolds config, installs tools, renders a readiness board, and rehearses the whole pipeline as a dry run.
  8. Signing status at a glance. launch setup ios reports active account, App ID, capabilities, certificate, profile, and registered devices — with --provision to ensure them.
Configure App Store Connect — as code

Each is declared in launch.config.ts (or a *.config.json sidecar) and reconciled with a read-only plan → your confirmation → apply — idempotently, never touching a live or in-review version. This is the surface EAS leaves to the website.

  1. Products, pricing & listing. launch sync reconciles in-app purchases, subscriptions, capabilities, and pricing onto App Store Connect — plus the per-locale listing copy, screenshots, and app previews — across every app at once.
  2. Preview & gate drift. launch plan [surface] diffs launch.config.ts against live App Store Connect and Google Play state read-only across every config-as-code surface — capabilities, IAPs, subscriptions, pricing, listing and screenshots, plus release attributes, offers, Game Center, App Clips, availability, accessibility, experiments, custom pages, and team-level Wallet & EU distribution; launch drift fails CI when they've diverged.
  3. Subscription offers. launch offers reconciles offer codes and promotional, introductory & win-back offers, plus the promoted-purchase order; offers generate-codes/list/deactivate drive campaigns from the CLI.
  4. Release attributes. launch release-config reconciles the age rating, categories, base price, and App Review details (contact + demo account) onto the editable version.
  5. Store availability. launch availability sets the App Store territories the app sells in.
  6. Custom product pages. launch custom-pages reconciles alternate App Store listings.
  7. Product-page A/B tests. launch experiments reconciles product-page experiments and their treatments.
  8. In-app events. launch events list/create/localize/delete manages App Store in-app events and their localizations.
  9. Game Center. launch game-center reconciles achievements and leaderboards.
  10. Accessibility labels. launch accessibility reconciles the accessibility nutrition labels.
  11. App Clips. launch app-clips reconciles each App Clip card's action and per-locale subtitle.
  12. Wallet & Apple Pay ids. launch wallet registers Apple Pay merchant ids and Wallet pass type ids.
  13. EU distribution (DMA). launch eu-distribution authorizes alternative-distribution domains and registers the package-signing key.
  14. Listing round-trip. launch metadata pull/push syncs the full store listing for iOS and Android — eas metadata is iOS-only.
Configure Google Play — as code
  1. Play products & subscriptions. launch play-products and launch play-subscriptions reconcile your Play in-app products and subscriptions (base plans + offers) from the same launch.config.ts catalog that drives App Store Connect.
  2. Tracks. launch play-tracks shows track status and promotes a build to a track at a chosen rollout with release notes, and reads/sets tester groups.
  3. Play reviews. launch play-reviews list/reply reads Play customer reviews (with optional machine translation) and posts replies — without the Play Console.
Build & ship — iOS and Android
  1. One command per platform. launch build ios / launch build android runs prebuild → sign → size-check → upload to the testing track (TestFlight / Play internal) — the same flow EAS runs.
  2. The full Apple platform family. launch build tvos, launch build macos, and launch build visionos join ios as first-class build targets — each archived with the right Xcode destination and signed with the matching App Store Connect profile type, on the same Apple Developer account and distribution certificate as iOS. Every non-iOS Apple target builds from its committed native project (react-native-tvos / react-native-macos / react-native-visionos).
  3. Fast by default. ccache wires in at pod install, DerivedData stays warm, and a native-graph fingerprint forces a clean build only when your native deps actually change; --clean forces from scratch.
  4. Build-time ETA & progress bar. A learned per-build estimate drives a live progress bar; --verbose streams the raw xcodebuild/Gradle output instead.
  5. Real download-size check. Reports the actual per-device size (App Thinning report / bundletool) and gates on the sizeBudgetMB you configured.
  6. Safety nets. Refuses to upload a simulator build, a .app, or an empty artifact; --dry-run rehearses the whole pipeline with no network, build, or account changes.
  7. Keep server vars out of the app. An envExclude denylist in launch.config.ts (exact names or PREFIX* wildcards) drops backend-only environment variables before the build, so they're never injected into the shipped bundle.
  8. Deliberate public release. The testing track is the default; launch release <platform> drives the public store over the API end to end — version, compliance, notes, rollout, submit — with no portal.
  9. Steer the rollout. launch status [--watch] tracks the review with CI exit codes; launch rollout pause/resume/complete steers an iOS phased release.
  10. Coordinated release train. launch release-train drives an app's iOS, Android, and OTA legs as one resumable record — start/status/release/abort, with --hold to gate every leg until all are approved and release them together, --platform/--no-ota to scope it, and --watch to poll until it settles.
  11. Re-sign without rebuilding. launch build:resign re-signs a stored .ipa/.aab with different credentials straight from the artifact.
  12. Completion notifications. A notify block pings a Slack/Discord webhook and/or runs a shell hook when a build or submit finishes — on success and failure.
Build without a Mac
  1. Cloud Mac in your own AWS. launch build ios --remote aws provisions an EC2 Mac, builds over SSH, and auto-releases it near the 24-hour billing floor; launch cloud manages the host lifecycle and shows running cost.
  2. Any Mac over SSH. launch build ios --remote user@host builds on a Mac you already have, with no allocation and no billing.
  3. Hand off to EAS. Set buildEngine: "eas" to delegate the build to Expo's cloud and still ship through Launch — handy for migrating incrementally.
Distribute & update
  1. Internal distribution. launch build <platform> --distribution internal hosts an ad-hoc iOS install link / Android .apk on your own bucket; register testers with launch device add <udid>.
  2. Over-the-air updates. launch update publishes a code-signed JS/asset update via the Expo Updates protocol your expo-updates runtime already speaks, hosted on your own bucket (S3 / R2 / Supabase).
  3. Roll back a bad update. launch updates list/view show the per-channel history; launch updates rollback promotes a known-good update or drops clients back to the embedded bundle.
  4. Pluggable storage. Artifacts and updates live in local storage or your own S3 / R2 / Supabase bucket, served from a URL you control — no hosted service.
Manage testers, team, reviews & reports — API-key only
  1. TestFlight from the CLI. launch testflight groups/create-group/testers/add/rm manages beta groups and invites testers, and testflight release submits a build for Beta App Review — no Apple-ID password, no 2FA.
  2. Reviews, read & reply. launch reviews list/reply/delete reads App Store reviews (filter by rating/territory) and posts, replaces, or removes the developer response.
  3. Sales, finance & analytics. launch reports sales/finance/analytics downloads App Store Connect's reports (gzipped TSV, or --json) straight to your machine.
  4. Team & access. launch team list/invite/remove reads and manages App Store Connect team members and pending invitations over the same API key.
  5. Sandbox testers. launch sandbox list/clear lists your StoreKit sandbox testers and clears their purchase history for clean in-app-purchase re-tests.
Inspect & debug
  1. Build history. launch builds list/view/log/prune reads the local artifact index — ids, per-device sizes, paths, and redacted logs — and prunes binaries past the retention window.
  2. Install & run. launch run [id|latest] installs a built artifact onto a connected device (adb/bundletool for Android, devicectl for iOS).
  3. Explain a failure. launch diagnose maps an xcodebuild/Gradle/CocoaPods error to a plain-English cause and fix.
  4. Why clean vs incremental. launch fingerprint shows the native fingerprint and why the next build will be clean or incremental.
  5. Tell your Apple accounts apart. launch creds leads its account summary with the app names each API key can see, so you know which Apple account — and which apps — a build will use before you ship.
Onboarding, teaching & maintenance
  1. Animated launch banner. A glowing pixel-art LAUNCH wordmark with an aurora violet→cyan gradient greets you on startup — an adoptable banner style that still degrades to plain text under NO_COLOR.
  2. Zero-setup demo. launch demo replays a simulated walkthrough of the whole build → sign → submit pipeline, and auto-plays once on first run.
  3. Teaching on demand. --explain on any command and launch explain <topic> cover the Apple/iOS/Android terminology inline.
  4. Interactive wizard. Running bare launch opens a guided wizard that remembers your last flow and offers a one-keypress repeat.
  5. Drive it from an AI agent. launch agents init/check scaffolds Claude Code / Cursor / Codex skills so coding agents run the workflows under the same plan → confirm → apply guardrails.
  6. CI in one command. launch ci init scaffolds a GitHub Actions workflow that builds and ships unattended.
  7. Silent self-upgrade. Picks up a newer npm release and re-runs your command on it — throttled to once a day, and a no-op in CI, when piped, and for agents.

Launch vs EAS

Launch runs the same eas buildeas submiteas update pipeline (plus eas metadata and eas credentials) on hardware you own — and covers the store-setup steps EAS leaves to you. Where the two differ on the same workflow:

In Expo EAS In Launch
Build compute runs on Expo's cloud, $19–$199/mo + per-build fees Builds on your own machine$0 compute, MIT-licensed, unlimited builds
Builds queue in a shared cloud, sometimes for hours Builds start immediately on your hardware — no queue
Free-tier builds are capped at a 45-minute timeout No timeout — a build runs as long as it needs
Apple-ID 2FA prompts / expired codes interrupt builds Authenticates with an App Store Connect API key (JWT) — no password, no 2FA
Toolchain/Node.js pinned by the build image; local .env not resolved Your own Xcode/Node/toolchain and a documented env-precedence ladder (--print-env to audit)
In-app purchases & subscriptions are hand-work in the ASC UI launch sync reconciles IAPs, subscriptions & capabilities from launch.config.ts
EAS rewrites bundle-id capabilities every build (clobbers toggles) launch sync applies a minimal safe-diff — capabilities it doesn't manage stay untouched
eas metadata is iOS-only launch metadata syncs the listing for iOS and Android
Play IAPs, subscriptions, tracks & reviews mean the Play Console UI launch play-products / play-subscriptions reconcile Play from the same config; launch play-tracks / play-reviews drive tracks & replies over the API
Game Center, Wallet, App Clips, in-app events, A/B experiments, territories & accessibility are portal-only Each is config as codelaunch game-center / wallet / app-clips / events / experiments / availability / accessibility
After eas submit, the App Store release (version, compliance, notes, rollout) is portal hand-work launch release drives it over the API — then launch status --watch and launch rollout track and steer it
Reviews, reports & TestFlight management mean a trip to the website launch reviews / launch reports / launch testflight do them over the API key — no portal
EAS Update hosts your OTA updates on Expo's servers (paid) launch update serves the same Expo Updates protocol from your own bucket (S3/R2/Supabase)
Internal-distribution builds are hosted by Expo --distribution internal hosts the ad-hoc .ipa/.apk on your own bucket; launch device
Signing credentials can live on Expo's servers Keys stay in your OS keychain — only a CSR ever leaves your machine
Build artifacts are hosted on Expo Artifacts land in your own storage (local, or S3 / R2 / Supabase)
No Mac? EAS's paid cloud is the only path No Mac? A cloud Mac in your own AWS, any Mac over SSH, or hand off to eas build
Closed SaaS — proprietary, vendor lock-in MIT, open sourcefastlane/Gradle/platform APIs, swappable providers, nothing to migrate

Requirements

  • iOS: an Apple Developer Program membership ($99/yr) — enroll here — then macOS with Xcode + command-line tools, fastlane (brew install fastlane), and an App Store Connect API key (.p8 + Key ID + Issuer ID) — generate one here. No Mac? See Building without a Mac.
  • Android: a Google Play Developer account (one-time $25) — register here — then a JDK (any OS — no Mac needed) and a Google Play service account JSON key.
  • Node.js 20+ on every platform.

Run launch doctor any time to check all of the above.

Install

Install from npm:

npm install --save-dev launch-store     # per-project (recommended; resolves the typed launch.config.ts)
npm install --global launch-store       # or global, for just the `launch` command

The quick start below uses npx launch, which resolves the per-project install. If you installed globally, drop npx.

Quick start

Try the whole pipeline first, with no Apple or Google setup:

npx launch demo

When you're ready to run against a real app, go from config to the testing track in five commands (swap iosandroid for Google Play):

npx launch init                 # scaffold launch.config.ts + .env.example, tailored to your repo
npx launch creds set-key        # import your store API key into the OS keychain
npx launch creds setup          # register the app id + create/reuse signing assets
npx launch build ios --dry-run  # rehearse the whole flow — no network, no build, no account changes
npx launch build ios            # build, sign, size-check, and upload to the testing track

launch build reuses your cached credentials silently; if they're missing it offers to provision them inline. Public release is the separate, deliberate launch release <platform>.

Selling in-app purchases or subscriptions? Declare them in launch.config.ts and run launch sync to create and reconcile them on App Store Connect — no clicking through the portal.

Already shipping an app? launch adopt reads your live App Store Connect setup — products, capabilities, signing, and listing — and writes it back into config in one step, so you can drive it forward with sync.

Commands

The everyday ones:

Command What it does
launch build <ios|android> Run the full pipeline — prebuild, sign, build, size-check, upload to the testing track.
launch release <ios|android> Ship the latest build to the public store, with confirmation.
launch update Publish an over-the-air JS update (Expo Updates protocol) to your own bucket.
launch sync Reconcile App Store Connect products, pricing, and the listing from launch.config.ts.
launch adopt Onboard an app that already ships — import its App Store Connect setup into config.
launch creds Inspect credentials, import the API key, provision signing, switch Apple accounts.
launch doctor Check that the local toolchain and store account are ready.

Full command reference → docs/commands.md — all 63 commands and every flag, generated from the CLI so it never drifts. Or run launch <command> --help.

Driving Launch from an AI agent? launch agents init scaffolds ready-made skills into your repo — Claude Code Skills (.claude/skills/), Cursor rules (.cursor/rules/), and a Launch section in AGENTS.md for Codex — so Claude Code, Cursor, and Codex can run the workflows above (ship, release, store-config-as-code, OTA updates, CI, and launch doctor) with the same plan → confirm → apply guardrails Launch uses, and never publish without your say-so. launch agents check keeps them in sync.

Read next:

Configuration

App facts (bundle id, version) are read from each app's Expo config — app.json or app.config.{ts,js} — so they're never duplicated. launch.config.ts holds only Launch-specific settings:

import { defineConfig } from "launch-store";

export default defineConfig({
  // appRoots: ["./apps"],   // for a monorepo; omit to scan the repo root
  credentials: "local", // OS keychain + ~/.launch
  storage: "local", // ~/.launch/artifacts (swap for s3/r2/supabase later)
  buildEngine: "fastlane", // "fastlane" (local Mac) · "remote-mac" (AWS EC2 Mac) · "eas" (Expo cloud)
  // submit: "app-store-connect", // or "eas" to submit through Expo

  // Only needed to build iOS without a Mac via `--remote aws` — see "Building without a Mac".
  // aws: { region: "us-east-1" },

  profiles: {
    // `env` is inline per-profile vars; `envFile` renames the base dotenv. Precedence, highest first:
    // --env flags › keychain secrets › profile `env:` › .env.local (--include-local) › .env.<profile> › .env
    production: {
      name: "production",
      envFile: ".env",
      env: {},
      sizeBudgetMB: 200,
    },
  },

  // Ping a Slack/Discord webhook and/or run a shell hook when a build or submit finishes (success or
  // failure). Both fields are optional; omit `notify` entirely for no notifications.
  // notify: { webhookUrl: "https://hooks.slack.com/services/…", command: "say build done" },

  // In-app purchases & subscriptions, keyed by bundle id — `launch sync` reconciles these onto App Store
  // Connect (and `launch play-products` / `play-subscriptions` onto Google Play). Capabilities aren't
  // declared here; they're read from app.json's `ios.entitlements`. Omit if your app sells nothing.
  // products: { "com.company.app": { subscriptionGroups: [/* … */], inAppPurchases: [/* … */] } },

  // Launch-native App Store Connect sections — each reconciled by its own command, declared inline here
  // (or, for back-compat, as a standalone `*.config.json` sidecar). Per-app ones are keyed by iOS bundle
  // id; Wallet & EU distribution are team-level. See examples/hello-world for a worked copy of each.
  // gameCenter: { "com.company.app": { achievements: [/* … */], leaderboards: [/* … */] } },
  // appClips: { "com.company.app": { clips: { "com.company.app.Clip": { action: "OPEN" } } } },
  // releaseAttributes: { "com.company.app": { pricing: { customerPrice: 9.99 }, categories: { primary: "PRODUCTIVITY" } } },
  // wallet: { merchantIds: [/* … */], passTypeIds: [/* … */] },
  // euDistribution: { domains: [/* … */] },
});

Run launch build <platform> --print-env to see the fully resolved environment and where each value came from (secrets masked), before a single build runs. A full-feature, dual-platform (iOS + Android) example — exercising every config-as-code surface, from products, offers, and release attributes to Game Center, Wallet, EU distribution, and the Google Play catalog — lives in examples/hello-world (see its README for a feature-by-feature tour).

Building without a Mac

iOS signing is macOS-only, so a Windows/Linux developer needs a Mac somewhere. Run launch (the wizard) or pick a path directly. Android builds anywhere a JDK runs, so none of this applies to it.

Path What happens Cost
AWS cloud Mac Launch provisions an EC2 Mac in your own AWS account, builds + signs + submits, then tears it down. You pay AWS directly — ~$16 minimum per 24h session (Apple's license sets a hard 24h floor).
Connect a Mac (SSH) Build on any Mac you can reach — a colleague's, MacStadium, a hand-launched instance. Whatever that Mac costs you.
Expo EAS Launch orchestrates eas-cli end-to-end (eas build → download → eas submit) on Expo's cloud. Expo's free tier with monthly caps.
launch build ios --remote aws            # build on a cloud Mac in your AWS account
launch build ios --remote ec2-user@host  # build on a Mac you reach over SSH
launch cloud doctor                      # check AWS creds, region, Mac-host quota, IAM
launch cloud status                      # live host: age, cost so far, releasable-after time
launch cloud teardown                    # stop + release the host (warns about the 24h floor)

Remote builds upload a transient copy of your signing keys to your own host with explicit consent and shred them after — never to anyone else's servers. For occasional iOS builds a GitHub Actions macOS runner is cheaper than EC2 Mac; Launch's value here is automation in your own account with the same keys everywhere.

How your credentials are handled

  • The API key (.p8), distribution private key, and Android upload key live in your OS keychain.
  • The iOS certificate is also backed up as a password-protected .p12 under ~/.launch/credentials/ (chmod 600); the password is stored in the keychain, never beside the file.
  • Your private key is generated locally — only a CSR is ever sent to Apple.
  • Launch reuses an existing distribution certificate instead of creating new ones (the stores cap them).

FAQ

What is Launch?

Launch is an open-source, self-hosted alternative to Expo EAS: it builds, signs, and ships Expo / React Native apps to TestFlight and Google Play from your own machine, with your own keys, and no per-build bill. It runs the same build → submit → update pipeline EAS does, and adds the store-setup steps EAS leaves to the App Store Connect and Play Console websites — in-app purchases, subscriptions, capabilities, and listing metadata — as code.

Is Launch a free, open-source alternative to Expo EAS?

Yes. Launch is MIT-licensed and fully open source, and builds run on hardware you own, so there is no per-build fee, build-minute meter, or monthly subscription — versus EAS's $19–$199/mo paid tiers plus per-build overage. The only optional cost is renting a cloud Mac if you need to build iOS without one.

How is Launch different from Expo EAS?

EAS runs your builds on Expo's cloud and keeps your credentials, artifacts, and OTA updates on Expo's servers. Launch runs the identical pipeline on your own machine, keeps signing keys in your OS keychain, and stores artifacts and OTA updates in your own bucket (S3 / R2 / Supabase) — then manages the store config EAS does not (IAPs, subscriptions, capabilities, and the iOS and Android listing) as code. The commands map one-for-one: eas buildlaunch build, eas submitlaunch release, eas updatelaunch update, eas metadatalaunch metadata, eas credentialslaunch creds.

Can I build iOS apps without a Mac?

iOS code signing and the build toolchain are macOS-only, so a Mac has to be in the loop — but it does not have to be yours. Launch can provision a cloud Mac in your own AWS account (an EC2 Mac), build over SSH on any Mac you can reach, or hand off to Expo EAS's cloud. Android builds anywhere a JDK runs, with no Mac at all.

Does Launch support Android and Google Play?

Yes. Launch builds and signs Android apps and uploads them to Google Play, and it reconciles Play in-app products, subscriptions (base plans + offers), release tracks, and review replies from the same launch.config.ts catalog that drives App Store Connect — one source of truth for both stores.

Does Launch do over-the-air updates like EAS Update?

Yes. launch update publishes JS and asset updates over the Expo Updates protocol your expo-updates runtime already speaks — code-signed and hosted on your own bucket (S3 / R2 / Supabase) instead of Expo's servers. launch updates rollback reverses a bad release by promoting a known-good update or dropping clients back to the embedded bundle.

How do I migrate from Expo EAS to Launch?

Swap the commands one-for-one (eas buildlaunch build, eas submitlaunch release, eas updatelaunch update, eas credentialslaunch creds, eas metadatalaunch metadata). If your app already ships, launch adopt reads its live App Store Connect setup — products, capabilities, signing, and listing — and writes it back into launch.config.ts in one step. Launch can also still hand off to eas build when you have no Mac, so you can migrate incrementally.

Is Launch just an App Store Connect SDK or MCP wrapper?

No. An App Store Connect SDK or MCP server wraps a slice of Apple's API. Launch drives the entire release across Apple and Google — code signing, native builds, size checks, store-config-as-code, the confirmed public release, and OTA updates — none of which an API wrapper touches. If you want a self-hosted Expo EAS rather than an API client, that is Launch.

How is Launch different from Fastlane?

Fastlane is a building block; Launch orchestrates it. Launch drives fastlane for the iOS archive (gym), the TestFlight / App Store upload (pilot), and store-listing metadata (deliver / supply), and wraps the whole release around it: credential provisioning, the native build, the real download-size check, store-config-as-code for both stores, the deliberate public release, phased-rollout control, and OTA updates — all from one typed launch.config.ts.

Where are my signing keys and secrets stored?

In your OS keychain. Your App Store Connect API key (.p8), distribution private key, and Android upload key never touch the repo or anyone's servers — only a certificate-signing request (CSR) is ever sent to Apple. Build secrets live in the keychain too, via launch secret, so they stay out of a committed .env.

What do I need to run Launch?

Node 20+ everywhere. For iOS: macOS with Xcode and its command-line tools, fastlane, and an App Store Connect API key (.p8 + Key ID + Issuer ID) — or a remote Mac if you do not have one. For Android: a JDK (any OS) and a Google Play service-account JSON key. Run launch doctor to check it all at once.

How much does Launch cost?

Launch itself is free (MIT). You pay only for what you would pay anyway: your own build hardware (or cloud-Mac time if you build iOS without a local Mac), plus the usual Apple Developer ($99/yr) and Google Play (one-time $25) registration fees. There is no per-build charge and no subscription.

Does Launch run in CI?

Yes. launch ci init scaffolds a GitHub Actions workflow on a hosted macOS runner, and every command degrades to non-interactive when it detects CI, a piped stdout, or an agent — so the same flow runs unattended.

What frameworks does Launch support?

Expo and bare React Native apps that describe themselves through Expo config (app.json / app.config.{ts,js}) and expo prebuild. Launch reads your bundle id, version, and entitlements from there, so nothing is duplicated.

Can Launch manage store metadata, in-app purchases, and subscriptions?

Yes — as code, for both stores. launch sync reconciles IAPs, subscriptions, pricing, capabilities, and the per-locale listing (copy, screenshots, previews) onto App Store Connect; launch metadata covers the listing for iOS and Android; launch play-products / launch play-subscriptions drive the Google Play catalog. Each runs a read-only plan → confirm → apply, so it never clobbers a live or in-review version.

Does Launch lock me into a hosted service?

No — there is nothing hosted and nothing proprietary. Launch is MIT-licensed, built on fastlane, Gradle, and the platforms' own APIs, with pluggable storage / credentials / build / submit providers. Your keys, artifacts, and updates live in infrastructure you control, so there is nothing to migrate off later.

How do I get started?

Install with npm install --global launch-store (or --save-dev per project), then run launch demo for a 60-second simulated walkthrough — no setup or account needed. When you are ready: launch initlaunch creds set-keylaunch creds setuplaunch build ios.

Contributing

See CONTRIBUTING.md for dev setup, the quality gate, and how to add a backend.

Contributors

YosefHayim

All contributors →

License

MIT


Launch is an open-source Expo EAS alternative — a local, self-hosted way to build and ship React Native apps to the App Store and Google Play from your own machine: iOS code signing, TestFlight & Google Play submission, store config as code, and Expo-protocol OTA updates, with no per-build bill.

About

Self-hosted CLI for building, signing, and shipping Expo/React Native apps to TestFlight and Google Play.

Topics

Resources

License

Contributing

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors