VibeView builds iOS, Apple TV, Android and Android TV apps in the cloud, with no Mac. It submits them to TestFlight, Google Play and the Amazon Appstore, and opens the simulator builds of the same project on live cloud devices.
This page is for Expo and React Native teams who submit with eas submit, or with the EAS Workflows submit and testflight jobs, and want to move that step. For the build step, see Build an Expo app without EAS. For a side-by-side of the two services, see EAS Build alternative: VibeView vs Expo EAS.
Who this is for
- Your
eas.jsonhas asubmitprofile and you runeas submit, oreas build --auto-submit[5]. - You need more than internal groups. Plain
eas submitadds a build to internal groups only[1]. External groups, What to Test notes and Beta App Review go through the separate Workflowstestflightjob[3]. In VibeView they are flags on the same command. - You ship Google Play release notes, which EAS Submit doesn’t manage[4], or an Apple TV, Android TV or Fire TV build of the same app.
Option mapping
vibeview.json below means platforms.ios.submit (also tvos) or platforms.android.submit (also androidtv). Flags are vibeview submit flags and always win over vibeview.json.
iOS and Apple TV
EAS names are from Expo’s eas.json reference[1], its App Store submission guide[5] and the Workflows testflight job[3].
| EAS | VibeView | Notes |
|---|---|---|
ascApiKeyPath, ascApiKeyIssuerId, ascApiKeyId | vibeview credentials asc-key add once, then ascKey or --asc-key | Stored once in VibeView. With a single key stored, there’s nothing to set. |
appleId, appleTeamId, app-specific password | No equivalent | VibeView never signs in with an Apple ID; it uses the API key only. |
ascAppId | Nothing to set | vibeview submit --check looks the app up by its bundle identifier, from the app linked in vibeview.json. |
bundleIdentifier | appId in vibeview.json | --bundle-id with --check. |
groups | groups, or --group "QA team" | Internal and external groups alike. A --group flag replaces the list. |
internal_groups, external_groups | --group (repeat it) | VibeView reads whether each group is internal or external from App Store Connect. |
changelog | --what-to-test "…" or --what-to-test-file | Up to 4,000 characters; required for an external group. Other languages: --notes-dir (CLI 0.58.0 or later). |
submit_beta_review | Automatic for an external group | VibeView sends the build to Beta App Review and adds it to your external groups; Apple releases it after approval. |
wait_processing_timeout_seconds | --wait-distribution | Follows processing, export compliance, notes, groups and review, with exit codes 0, 1 and 2, up to 2 h 15 min. Without the flag, VibeView keeps checking App Store Connect after the command exits and shows each step on the build’s page. |
eas build --auto-submit | --auto-submit on vibeview build --cloud --production | Sends each build to TestFlight once it succeeds, with your submit settings and --what-to-test, and follows the upload until Apple has it (CLI 0.62.0 or later). VibeView keeps following TestFlight distribution after that. |
eas submit --latest | vibeview submit --latest | The newest succeeded production build for --platform. In CI, pass --build <id> instead. |
metadataPath (EAS Metadata) | No equivalent | Store listing and screenshots stay in App Store Connect. |
sku, companyName, appName, language | No equivalent | Create the app record in App Store Connect once (Apps → + → New App). |
Apple’s export compliance question is answered once per app in VibeView. --uses-encryption or --no-uses-encryption saves the answer for later builds, and ITSAppUsesNonExemptEncryption in your Info.plist wins over it.
Android and Android TV
EAS names are from the Android options in Expo’s eas.json reference[2]; the release-notes row is from its submission overview[4].
| EAS | VibeView | Notes |
|---|---|---|
serviceAccountKeyPath | vibeview credentials play-key add | Stored once in VibeView, like the App Store Connect key. |
track | track or --track | internal, alpha, beta or production. |
releaseStatus | releaseStatus or --release-status | completed, draft or inProgress. There’s no halted: halt a release in Play Console. |
rollout | rollout or --rollout | A fraction between 0 and 1, with inProgress, as in EAS. |
changesNotSentForReview | changesNotSentForReview | Same key name; the flag is --changes-not-sent-for-review. |
applicationId | --package | Only for a build not linked to an app. |
| No release notes in EAS Submit | --release-notes plus --notes-dir | Up to 500 characters per language. |
See Google Play tracks, staged rollout and changes not sent for review for the Play terms.
What has no equivalent
- Submitting a binary built elsewhere. EAS Submit accepts any valid
.ipaor.aab, including a local build passed with--path[4]. VibeView submits its own cloud builds only. - Distributing a build already in App Store Connect. The
testflightjob’sasc_build_id[3] has no VibeView counterpart. - Store metadata. EAS Metadata (
metadataPath)[1] has no counterpart. Listings, screenshots, App Store review and phased release stay in App Store Connect. - Creating the App Store Connect app. EAS Submit can create the app record when
ascAppIdisn’t set[1]. With VibeView you create it once by hand. - Apple ID sign-in. VibeView works with an App Store Connect API key only.
Before and after
An EAS setup that submits Android to a staged beta and iOS to an internal group, plus the Workflows job that adds an external group and a note[2][3]:
{
"submit": {
"production": {
"ios": {
"ascAppId": "1234567890",
"ascApiKeyPath": "./keys/AuthKey_ABC123.p8",
"ascApiKeyIssuerId": "00000000-0000-0000-0000-000000000000",
"ascApiKeyId": "ABC123",
"groups": ["QA team"]
},
"android": {
"serviceAccountKeyPath": "./keys/play-service-account.json",
"track": "beta",
"releaseStatus": "inProgress",
"rollout": 0.1
}
}
}
}
# .eas/workflows/testflight.yml
jobs:
build_ios:
type: build
params:
platform: ios
profile: production
testflight:
type: testflight
needs: [build_ios]
params:
build_id: ${{ needs.build_ios.outputs.build_id }}
internal_groups: ['QA team']
external_groups: ['Public beta']
changelog: 'Try the new checkout'
The same on VibeView. The keys are stored once with vibeview credentials, so vibeview.json names no key files:
{
"platforms": {
"ios": {
"appId": "app_ios123",
"build": { "...": "..." },
"submit": { "ascKey": "team", "groups": ["QA team", "Public beta"] }
},
"android": {
"appId": "app_android456",
"build": { "...": "..." },
"submit": { "track": "beta", "releaseStatus": "inProgress", "rollout": 0.1 }
}
}
}
vibeview build --cloud --production --platform all
vibeview submit --platform ios --latest --what-to-test "Try the new checkout" --wait-distribution
vibeview submit --platform android --latest --release-notes "Try the new checkout"
Switch step by step
One trap first. Apple and Google refuse a build number they have already seen. While EAS and VibeView both upload the same app, check VibeView’s counter with vibeview versions list before each VibeView build, and raise it with vibeview versions set if EAS uploaded a higher number since (step 4).
-
Keep EAS running. VibeView doesn’t read
eas.json, so both can live in the repository while you try it. Your store releases keep going through EAS until the last step. -
Set up cloud builds. Follow Build an Expo app without EAS up to the production profile: prebuild in the build command, config plugins for signing, and
autoIncrement, which gives each production build the next build number. Credentials that EAS manages stay with Expo: generate new ones withvibeview credentials generate, or upload copies of the files you have withvibeview credentials add. For an app already on Play, upload the same upload key your listing already trusts. -
Store the store keys. Add the App Store Connect key with
vibeview credentials asc-key addand the Play service account withvibeview credentials play-key add. They can be the same key fileseas.jsonpoints at today. The App Store Connect key needs the App Manager or Admin role to send builds to groups. -
Seed the build numbers. With an App Store Connect key stored, the first iOS number starts above your app’s existing builds. For Android, set the counter once from your latest version code:
vibeview versions set --app <app-id> --platform android <number> -
Check both stores. These confirm the stores know the apps and accept the keys, and exit
1if not:vibeview submit --check --platform ios --group "QA team" vibeview submit --check --platform android -
Send to internal testers first. Compare what arrives with what EAS sends. Move on only after two builds in a row arrive the same way.
vibeview submit --platform ios --latest --group "QA team" vibeview submit --platform android --latest --track internal -
Add the external details once.
vibeview testflight infolists what Apple needs before external testing (beta test information, the Beta App Review contact).vibeview testflight set-infoandset-review-contactfill it in, or use TestFlight details in the dashboard. -
Move external groups and CI. Add the external group and send one build with
--what-to-test. Then replace the EAS jobs with GitHub Actions to TestFlight, no Mac runner, or your own CI adding--auto-submittovibeview build --cloud --production, with a CI-only token. Remove thesubmitprofiles fromeas.jsonwhen nothing uses them.
Where EAS is the better fit
- Any binary. EAS Submit uploads any valid
.ipaor.aab, wherever it was built[4]; VibeView submits its own builds. - Store metadata. EAS Metadata manages App Store information and localized descriptions[4]; VibeView leaves the listing to App Store Connect.
- App record creation and Apple ID sign-in[1][5], for teams that don’t use API keys.
- Price. Expo’s Free plan includes submitting to the app stores[7]. On VibeView, submitting needs a VibeView production build, which uses your plan’s build minutes.
What VibeView adds:
- External groups, What to Test and Beta App Review on the
vibeview submitcommand. - Google Play release notes in each language.
- One submission state that names what is missing and where to fix it, with Check again.
- A notification when testers have the build, and an email when it fails or Apple needs something from you, with matching Slack and webhook events. EAS reports a submission’s result through webhooks[6].
- The export compliance answer saved once per app.
- Amazon Appstore submission for Android and Android TV.
- The same project on cloud iOS, Android, Apple TV and Android TV devices for testing.
Frequently asked questions
Is VibeView an EAS Submit alternative?
Yes, for TestFlight and Google Play. vibeview submit uploads a VibeView production build and
sends it to internal and external TestFlight groups with What to Test notes and Beta App
Review, or to a Google Play track with release notes and an optional staged rollout. It also
submits Android and Android TV .apk builds to the Amazon Appstore.
Does VibeView have an equivalent of eas build --auto-submit?
Yes. Add --auto-submit to vibeview build --cloud --production and each build goes to
TestFlight or Google Play as soon as it succeeds, with the same settings vibeview submit
reads, even if you close your laptop. You get a notification when testers have the build.
Can I keep EAS Build and only switch submission?
No. vibeview submit sends builds VibeView made, so the production build moves too. The
simulator and preview builds can move later, or stay where they are.
Do my eas.json submit settings carry over?
Not automatically: VibeView doesn’t read eas.json. Most Android keys keep their names in the
submit block of vibeview.json (track, releaseStatus, rollout,
changesNotSentForReview). On iOS, groups carries over and the key settings become one
stored key.
Does VibeView submit for App Store review?
No. VibeView gets builds to TestFlight testers, through Beta App Review for external groups. Submitting a version for App Store review stays in App Store Connect.
Next: move the build with Build an Expo app without EAS, then the pipeline with GitHub Actions to TestFlight. Coming from fastlane instead? See Migrate from fastlane pilot.
Sources
Every claim about Expo on this page comes from Expo's own documentation, read on the date shown. Products change: check the linked page before you rely on a detail.
- Expo eas.json reference: iOS submit options (docs.expo.dev/eas/json, checked ): eas.json submit, iOS-specific options: appleId, ascAppId ("When set, results in skipping the app creation step"), appleTeamId, sku, language, companyName, appName, ascApiKeyPath, ascApiKeyIssuerId, ascApiKeyId, bundleIdentifier, metadataPath ("The path to your store configuration file"), groups ("An array of TestFlight internal group names to add the build to")
- Expo eas.json reference: Android submit options (docs.expo.dev/eas/json, checked ): eas.json submit, Android-specific options: serviceAccountKeyPath, track (production, beta, alpha, internal), releaseStatus (completed, draft, halted, inProgress), rollout ("The initial fraction of users who are eligible to receive the release ... Works only with inProgress release status"), changesNotSentForReview, applicationId
- Expo EAS Workflows pre-packaged jobs (docs.expo.dev/eas/workflows/pre-packaged-jobs, checked ): EAS Workflows pre-packaged jobs: the submit job takes build_id, profile and groups ("TestFlight internal group names"); "If you need to control test groups, changelog, or Beta App Review submission, use the testflight job instead of submit"; the testflight job takes build_id or asc_build_id, internal_groups, external_groups, changelog ("What to Test"), submit_beta_review ("defaults to true when external_groups are provided, false otherwise") and wait_processing_timeout_seconds (default 1800)
- Expo: Submit to app stores (docs.expo.dev/submit/introduction, checked ): "EAS Submit accepts any valid .aab (Android App Bundle) or .ipa (iOS App Archive) file", with --path for local builds; "EAS Submit uploads your binary but does not manage store listing metadata, screenshots, or release notes"; "For Apple App Store, you can use EAS Metadata"; eas submit --platform android --latest --non-interactive in CI; it "works from any OS (including Windows and Linux for iOS)"
- Expo: Submit to the Apple App Store (docs.expo.dev/submit/ios, checked ): eas submit --platform ios "will walk you through selecting a build, prompt for your Apple ID on first run"; eas build --platform ios --auto-submit hands the finished build to EAS Submit; credentials are an App Store Connect API Key (eas credentials, or ascApiKeyPath, ascApiKeyIssuerId and ascApiKeyId) or an app-specific password in EXPO_APPLE_APP_SPECIFIC_PASSWORD
- Expo: Webhooks (docs.expo.dev/eas/webhooks, checked ): EAS webhooks take the event types BUILD and SUBMIT (eas webhook:create --event BUILD|SUBMIT); a SUBMIT payload carries status (errored, finished or canceled) and submissionInfo.error for a failed submission; the page names no built-in email or Slack notice, and its example server only suggests posting to Slack from your own handler
- Expo pricing (expo.dev/pricing, checked ): The Free plan ($0/month) includes "Submit to app stores"
Related guides
In the documentation
Try it yourself
Open a live iOS simulator, Android emulator, Apple TV, Android TV or Roku in your browser.
Start free