NewiPhone Duo, live in your browser. Try it →
Vibeview
Pricing
Cloud Builds · Android

Build a React Native Android app in the cloud

Rokas Kašinskas — Co-founder, VibeViewPublished 2026-10-07Updated 2026-10-16

Building an Android release normally means a working Android Studio install, the right JDK, a Gradle cache that eats your disk, and a keystore file that lives on one laptop. VibeView cloud builds move all of that off your machine. The CLI uploads your project source, the build runs in a clean environment, and you get back either a debug build you can run on a cloud Android emulator straight away, or a signed release you can send to Google Play from the same terminal.

This guide follows one app from source to the Play Console’s internal testing track: a debug .apk first, then a signed .aab, then the upload. It works the same from Windows, Linux or macOS.

What you need

  • A VibeView account and the CLI: npm install -g vibeview && vibeview login
  • A React Native project, bare or Expo (for a managed Expo project with no android/ folder, see Build an Expo app without EAS)
  • For the store step: a Google Play Console account with the app created in it, and a Google Cloud service account (covered below)

You don’t need Java, Gradle or the Android SDK locally. Every plan includes cloud builds each month; builds beyond your plan’s allowance draw from usage credit. The pricing page has each plan’s numbers.

Part 1: a debug build on a cloud emulator

  1. Start the build from your project root.

    vibeview build --cloud --platform android

    The first run asks for two things and saves them to vibeview.json: the build command, and where the finished file lands. For a bare React Native project the suggestion is a Gradle assembleDebug. Make sure the command installs your dependencies, because node_modules is never uploaded:

    {
      "defaultPlatform": "android",
      "platforms": {
        "android": {
          "build": {
            "command": "yarn install --immutable && cd android && ./gradlew assembleDebug",
            "artifact": "android/app/build/outputs/apk/debug/*.apk"
          }
        }
      }
    }

    Use whatever your lockfile calls for: npm ci, yarn install --immutable or pnpm install --frozen-lockfile.

  2. Watch the log. The CLI packs every file git tracks plus untracked files that .gitignore doesn’t exclude, uploads them, and streams the Gradle output. Add --no-wait to start the build and leave; vibeview builds logs <id> --follow picks it back up.

  3. Run it. A succeeded debug build lands in the app’s Build history with a cloud badge. If the project had no app yet, the build creates one from the binary and the CLI writes its appId into vibeview.json. Open the build’s page and choose Run this build to start it on a cloud Android emulator in the browser, or run vibeview dev --platform android to work on it with Metro and hot reload.

You’ll know it worked when the build page shows added to app builds on its timeline and the app launches on the emulator. If your build filters native ABIs, keep x86_64 in the list. VibeView’s Android emulators run x86_64 natively, and some of them can also run ARM code through ARM translation, but a translated app can crash at launch and an ARM-only build is limited to the devices that support it (Preparing your build has the details). React Native’s default architectures already include x86_64.

Part 2: a signed .aab for Google Play

A production build is a different artifact with a different job. It is signed with your release key, it is meant for the store, and it doesn’t install on a VibeView device. It shows up on the Builds page with a Download action instead of in Build history.

  1. Get a keystore. If you already have one, upload it; every password is prompted with hidden input, never passed as a flag:

    vibeview credentials add --platform android --file release.jks

    If you’ve never made one, let VibeView generate it. No keytool needed:

    vibeview credentials generate --platform android --name release

    This stores the keystore as a signing credential, saves a copy of the file locally and prints its passwords. Keep your own backup, though an organization admin can re-download a generated keystore later with vibeview credentials download release.

  2. Point Gradle at it. Add this block to android/app/build.gradle. VibeView sets the four properties only during a production build, and the hasProperty guard keeps your local debug builds unaffected:

    if (project.hasProperty('VIBEVIEW_STORE_FILE')) {
        signingConfigs {
            release {
                storeFile file(VIBEVIEW_STORE_FILE)
                storePassword VIBEVIEW_STORE_PASSWORD
                keyAlias VIBEVIEW_KEY_ALIAS
                keyPassword VIBEVIEW_KEY_PASSWORD
            }
        }
        buildTypes.release.signingConfig signingConfigs.release
    }

    Keep the signingConfig assignment inside the guard. A managed Expo project has no checked-in Gradle file, so it adds the same block with a small config plugin; the App Signing docs explain how.

  3. Turn on automatic version codes. Google Play refuses an upload that reuses a versionCode. Set autoIncrement and every production build gets the next number from a counter VibeView keeps per app and platform, passed to the build as VIBEVIEW_BUILD_NUMBER:

    // android/app/build.gradle, inside defaultConfig
    versionCode (System.getenv("VIBEVIEW_BUILD_NUMBER") ?: "1").toInteger()

    If the app is already on Play, seed the counter once with your current highest versionCode: vibeview versions set --app <app-id> --platform android <number> makes the next production build <number> + 1.

  4. Build the release.

    vibeview build --cloud --production --platform android

    The first run asks for the release command and offers a Gradle bundleRelease, which writes an .aab. Your vibeview.json then carries both builds side by side:

    {
      "platforms": {
        "android": {
          "appId": "my-app-abc123",
          "build": {
            "command": "yarn install --immutable && cd android && ./gradlew assembleDebug",
            "artifact": "android/app/build/outputs/apk/debug/*.apk",
            "productionCommand": "yarn install --immutable && cd android && ./gradlew bundleRelease",
            "productionArtifact": "android/app/build/outputs/bundle/release/*.aab",
            "autoIncrement": true
          }
        }
      }
    }

    Want a signed .apk instead, to hand to a tester outside the store? Point the release command at assembleRelease and the artifact at android/app/build/outputs/apk/release/*.apk. vibeview builds download <id> saves either file locally.

Part 3: upload the .aab to Google Play from the command line

Google’s publishing API can update an app but can’t create one, so do two one-time things first: create the app in Play Console (All apps → Create app), and set up a service account. In Google Cloud, create the account under IAM & Admin → Service Accounts and download its JSON key, enable the Google Play Android Developer API for that project, then invite the account’s email in Play Console under Users and permissions with release access. Store the key once:

vibeview credentials play-key add --file service-account.json

Check that Play knows your app before you spend a build on it. No build is needed:

vibeview submit --check --platform android --package com.example.myapp

Then upload:

vibeview submit --platform android --latest --track internal

--latest picks your newest succeeded production build. The package name is read from the .aab itself. Releases on internal, alpha and beta default to completed, so testers get them right away. On production the default is a draft that waits for you in Play Console. --release-status inProgress --rollout 0.1 starts a staged rollout to 10% of users instead. To skip the flags next time, put "submit": { "track": "internal" } next to the build block in vibeview.json.

The upload is the binary only. Store listing, screenshots and release notes stay in Play Console, exactly as if you had uploaded the file by hand. Eligible builds also get a Submit to store button on the dashboard’s Builds page.

Android TV uses the same keystore

An Android TV app needs no credential of its own. Android TV production builds sign with your Android keystore, so one key, uploaded or generated, covers your phone and TV builds. Build with --platform androidtv and submit with vibeview submit --platform androidtv --track internal. For a TV debug build, include both x86 and x86_64 native code so it runs on every Android TV emulator. The Apple TV and Android TV build guide walks through a TV project end to end.

Troubleshooting

  • Cannot find module or Couldn't find the node_modules state file. The build command never installed dependencies. Add npm ci (or your package manager’s equivalent) to the front of it.
  • Play refuses the upload as a duplicate version code. Turn on autoIncrement, or seed the counter above your highest existing versionCode with vibeview versions set.
  • “create the app in Play Console first”. The app doesn’t exist in Play Console yet, or its package name differs from the one in your build.
  • The service account “lacks release permission”. Invite its email in Play Console under Users and permissions and grant release access.
  • The production build fails as unsigned. The signingConfig assignment sits outside the hasProperty guard, or the block is missing. VibeView refuses an unsigned artifact when it supplied credentials.

Frequently asked questions

Frequently asked questions

Can I build an .aab without Android Studio?

Yes. The cloud build runs Gradle for you, and vibeview credentials generate --platform android creates the keystore without keytool. Your machine only needs Node.js for the CLI.

What if I lose the keystore?

New Play apps use Play App Signing by default, which makes your keystore an upload key: Google Play support can help reset a lost one. Apps on legacy direct signing can’t be updated without the original key. A keystore VibeView generated can be re-downloaded by an organization admin; an uploaded one can never be read back.

Can I run the signed .aab on a VibeView emulator?

No. Production builds are for the store and can’t be installed on a VibeView device. Test with the debug build from Part 1, which runs on a cloud Android emulator.

Do I still need a Mac for the iOS version?

No. The same commands build iOS on VibeView’s macOS builders and upload to TestFlight. See Upload to TestFlight without a Mac.

Next steps

Try it yourself

Open a live iOS simulator or Android emulator in your browser.

Start free