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.
English · 简体中文 · 日本語 · 한국어 · Español · Português · Français · Deutsch · Русский
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 demofor a 60-second simulated walkthrough of the whole pipeline — no setup, no build, no account needed. It also auto-plays the first time you runlaunch.
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.tsand a handful of commands — not a dozen dashboards and CI snippets. - Store setup as code.
launch syncreconciles in-app purchases, subscriptions, pricing, and capabilities onto App Store Connect from one typedlaunch.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 — pluslaunch metadatafor 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
--explainto any command — or runlaunch demo— to expand each step (CSR, provisioning profile, TestFlight, Play track, subscription group) into plain English.
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.
Set up & verify
- Config in one step.
launch initdetects your app(s) — including anapps/*monorepo — and writes a commentedlaunch.config.tsplus a starter.env.example, touching no credentials or native code. - Onboard a live app.
launch adoptimports an already-shipping app's App Store Connect setup — products, capabilities, listing, signing — back intolaunch.config.ts. - Keys in your keychain.
launch creds set-keyvalidates yourAuthKey_*.p8against Apple and vaults it in your OS keychain;creds use/rename/removeswitch between teams. - APNs push-key vault.
launch creds push-keysafe-keeps a download-once APNs auth key and re-exports it on demand — Apple exposes no API to recreate one. - Secrets, not plaintext
.env.launch secret set/list/rmstores build secrets in your OS keychain, scoped per app/profile, and injects them into the build env. - One-command doctor.
launch doctor --fixdetects the iOS/Android toolchain, installs the missing brew-able tools behind a single consent, and flags store-side blockers. - Hands-off setup.
launch setupscaffolds config, installs tools, renders a readiness board, and rehearses the whole pipeline as a dry run. - Signing status at a glance.
launch setup iosreports active account, App ID, capabilities, certificate, profile, and registered devices — with--provisionto 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.
- Products, pricing & listing.
launch syncreconciles 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. - Preview & gate drift.
launch plan [surface]diffslaunch.config.tsagainst 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 driftfails CI when they've diverged. - Subscription offers.
launch offersreconciles offer codes and promotional, introductory & win-back offers, plus the promoted-purchase order;offers generate-codes/list/deactivatedrive campaigns from the CLI. - Release attributes.
launch release-configreconciles the age rating, categories, base price, and App Review details (contact + demo account) onto the editable version. - Store availability.
launch availabilitysets the App Store territories the app sells in. - Custom product pages.
launch custom-pagesreconciles alternate App Store listings. - Product-page A/B tests.
launch experimentsreconciles product-page experiments and their treatments. - In-app events.
launch events list/create/localize/deletemanages App Store in-app events and their localizations. - Game Center.
launch game-centerreconciles achievements and leaderboards. - Accessibility labels.
launch accessibilityreconciles the accessibility nutrition labels. - App Clips.
launch app-clipsreconciles each App Clip card's action and per-locale subtitle. - Wallet & Apple Pay ids.
launch walletregisters Apple Pay merchant ids and Wallet pass type ids. - EU distribution (DMA).
launch eu-distributionauthorizes alternative-distribution domains and registers the package-signing key. - Listing round-trip.
launch metadata pull/pushsyncs the full store listing for iOS and Android —eas metadatais iOS-only.
Configure Google Play — as code
- Play products & subscriptions.
launch play-productsandlaunch play-subscriptionsreconcile your Play in-app products and subscriptions (base plans + offers) from the samelaunch.config.tscatalog that drives App Store Connect. - Tracks.
launch play-tracksshows track status and promotes a build to a track at a chosen rollout with release notes, and reads/sets tester groups. - Play reviews.
launch play-reviews list/replyreads Play customer reviews (with optional machine translation) and posts replies — without the Play Console.
Build & ship — iOS and Android
- One command per platform.
launch build ios/launch build androidruns prebuild → sign → size-check → upload to the testing track (TestFlight / Play internal) — the same flow EAS runs. - The full Apple platform family.
launch build tvos,launch build macos, andlaunch build visionosjoiniosas 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). - 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;--cleanforces from scratch. - Build-time ETA & progress bar. A learned per-build estimate drives a live progress bar;
--verbosestreams the rawxcodebuild/Gradle output instead. - Real download-size check. Reports the actual per-device size (App Thinning report / bundletool) and gates on the
sizeBudgetMByou configured. - Safety nets. Refuses to upload a simulator build, a
.app, or an empty artifact;--dry-runrehearses the whole pipeline with no network, build, or account changes. - Keep server vars out of the app. An
envExcludedenylist inlaunch.config.ts(exact names orPREFIX*wildcards) drops backend-only environment variables before the build, so they're never injected into the shipped bundle. - 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. - Steer the rollout.
launch status [--watch]tracks the review with CI exit codes;launch rollout pause/resume/completesteers an iOS phased release. - Coordinated release train.
launch release-traindrives an app's iOS, Android, and OTA legs as one resumable record —start/status/release/abort, with--holdto gate every leg until all are approved and release them together,--platform/--no-otato scope it, and--watchto poll until it settles. - Re-sign without rebuilding.
launch build:resignre-signs a stored.ipa/.aabwith different credentials straight from the artifact. - Completion notifications. A
notifyblock 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
- Cloud Mac in your own AWS.
launch build ios --remote awsprovisions an EC2 Mac, builds over SSH, and auto-releases it near the 24-hour billing floor;launch cloudmanages the host lifecycle and shows running cost. - Any Mac over SSH.
launch build ios --remote user@hostbuilds on a Mac you already have, with no allocation and no billing. - 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
- Internal distribution.
launch build <platform> --distribution internalhosts an ad-hoc iOS install link / Android.apkon your own bucket; register testers withlaunch device add <udid>. - Over-the-air updates.
launch updatepublishes a code-signed JS/asset update via the Expo Updates protocol yourexpo-updatesruntime already speaks, hosted on your own bucket (S3 / R2 / Supabase). - Roll back a bad update.
launch updates list/viewshow the per-channel history;launch updates rollbackpromotes a known-good update or drops clients back to the embedded bundle. - 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
- TestFlight from the CLI.
launch testflight groups/create-group/testers/add/rmmanages beta groups and invites testers, andtestflight releasesubmits a build for Beta App Review — no Apple-ID password, no 2FA. - Reviews, read & reply.
launch reviews list/reply/deletereads App Store reviews (filter by rating/territory) and posts, replaces, or removes the developer response. - Sales, finance & analytics.
launch reports sales/finance/analyticsdownloads App Store Connect's reports (gzipped TSV, or--json) straight to your machine. - Team & access.
launch team list/invite/removereads and manages App Store Connect team members and pending invitations over the same API key. - Sandbox testers.
launch sandbox list/clearlists your StoreKit sandbox testers and clears their purchase history for clean in-app-purchase re-tests.
Inspect & debug
- Build history.
launch builds list/view/log/prunereads the local artifact index — ids, per-device sizes, paths, and redacted logs — and prunes binaries past the retention window. - Install & run.
launch run [id|latest]installs a built artifact onto a connected device (adb/bundletoolfor Android,devicectlfor iOS). - Explain a failure.
launch diagnosemaps anxcodebuild/Gradle/CocoaPods error to a plain-English cause and fix. - Why clean vs incremental.
launch fingerprintshows the native fingerprint and why the next build will be clean or incremental. - Tell your Apple accounts apart.
launch credsleads 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
- Animated launch banner. A glowing pixel-art
LAUNCHwordmark with an aurora violet→cyan gradient greets you on startup — an adoptable banner style that still degrades to plain text underNO_COLOR. - Zero-setup demo.
launch demoreplays a simulated walkthrough of the whole build → sign → submit pipeline, and auto-plays once on first run. - Teaching on demand.
--explainon any command andlaunch explain <topic>cover the Apple/iOS/Android terminology inline. - Interactive wizard. Running bare
launchopens a guided wizard that remembers your last flow and offers a one-keypress repeat. - Drive it from an AI agent.
launch agents init/checkscaffolds Claude Code / Cursor / Codex skills so coding agents run the workflows under the same plan → confirm → apply guardrails. - CI in one command.
launch ci initscaffolds a GitHub Actions workflow that builds and ships unattended. - 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 runs the same eas build → eas submit → eas 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 code — launch 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 source — fastlane/Gradle/platform APIs, swappable providers, nothing to migrate |
- 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 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` commandThe quick start below uses npx launch, which resolves the per-project install. If you installed
globally, drop npx.
Try the whole pipeline first, with no Apple or Google setup:
npx launch demoWhen you're ready to run against a real app, go from config to the testing track in five commands
(swap ios → android 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 tracklaunch 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.
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 initscaffolds ready-made skills into your repo — Claude Code Skills (.claude/skills/), Cursor rules (.cursor/rules/), and a Launch section inAGENTS.mdfor Codex — so Claude Code, Cursor, and Codex can run the workflows above (ship, release, store-config-as-code, OTA updates, CI, andlaunch doctor) with the same plan → confirm → apply guardrails Launch uses, and never publish without your say-so.launch agents checkkeeps them in sync.
Read next:
docs/commands.md— the full generated command and flag reference.docs/config.md— the generatedlaunch.config.tsfield reference.examples/hello-world— a worked Expo / React Native app config.CONTRIBUTING.md— local development, tests, CI, and provider contribution flow.AGENTS.md,CLAUDE.md, andCODE-STYLE.md— rules for coding agents and contributors editing this repo.PROJECT.md,CONTEXT.md,LANGUAGE.md, anddocs/adr/— product direction, architecture context, domain language, and decisions.
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).
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.
- 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
.p12under~/.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).
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 build → launch build, eas submit → launch release, eas update → launch update, eas metadata → launch metadata, eas credentials → launch 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 build → launch build, eas submit → launch release, eas update → launch update, eas credentials → launch creds, eas metadata → launch 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 init → launch creds set-key → launch creds setup → launch build ios.
See CONTRIBUTING.md for dev setup, the quality gate, and how to add a backend.
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.


