> ## Documentation Index
> Fetch the complete documentation index at: https://docs.revyl.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Expo Builds

> Create iOS and Android for Expo apps

Create dev and preview builds for your Expo React Native app.

## Build Guidance

To use the [Dev Loop](../../develop/dev-loop-overview), a build is required **only on native code changes** (new native modules, Podfile/Gradle changes, build configuration). JS/TS changes hot reload via Metro — see [Dev Loop: Hot reload and rebuild configuration](../../develop/dev-loop-overview#hot-reload-and-rebuild-configuration) for the full breakdown.

## Build via Revyl CLI

### Prerequisites

* Node.js 18+
* Expo CLI (`npx expo`)
* EAS CLI (`npx eas-cli`) only when your authored recipe uses EAS
* Revyl CLI installed and authenticated (`revyl auth login`)

### Setup

Initialize the project using the Revyl CLI:

```bash theme={null}
revyl init
```

This detects Expo and writes named profiles with the applicable iOS and Android
recipes. Review or fill in the app IDs, commands, and output paths before the
first build. See [Types of Builds](/builds#types-of-builds) for more information.

### Choose a build approach

| Approach | Recipe | Expo authentication |
| - | - | - |
| Native prebuild (default in dashboard setup) | Run `expo prebuild`, then Xcode or Gradle directly | None required solely for Expo |
| EAS local build | Run `eas-cli build --local` | Use Expo login or `EXPO_TOKEN` locally; store encrypted `EXPO_TOKEN` for unattended remote builds |

Choosing the Expo framework does not itself require `EXPO_TOKEN`. Add that
secret only when the selected build command uses EAS or another project step
needs it. The dashboard leaves commands and secret references directly
editable; create any required secret inline or in the Library.

Development builds power the dev loop. Preview builds are for testing and starting sessions when the Metro server isn't needed.

### Run Build

Run one profile/platform recipe in the cloud:

```bash theme={null}
revyl build --profile development --platform ios
```

Profile names and their `ios` or `android` recipes live under
`build.profiles` in `.revyl/config.yaml`. There is no active/default profile.
See [Configuration](/remote-builds/configuration) for selection and recipe
fields.

This command automatically builds and uploads the app to Revyl, where you can use it to start sessions.

## Advanced Configuration

When you run `revyl init`, Revyl makes a best-effort guess at your configuration. This section covers configuration in more detail.

### EAS setup

This section applies only when an authored recipe uses EAS. Your `eas.json`
needs at least two profiles: one that includes the development client and one
that does not. See the following `eas.json` file as reference:

```json theme={null}
{
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "ios": {
        "simulator": true
      },
      "android": {
        "buildType": "apk"
      }
    },
    "preview": {
      "distribution": "internal",
      "ios": {
        "simulator": true
      },
      "android": {
        "buildType": "apk"
      }
    }
  }
}
```

Note that the iOS simulator is enabled for both profiles, and `developmentClient` is set to `true` only for the development profile.
Revyl executes the command arrays in `.revyl/config.yaml` as authored; it does
not rewrite `eas.json` or switch EAS profiles during a build.

### Build Commands and Hot Reload Setup

`revyl init` creates a `.revyl/config.yaml` file in the root of your project.
Each named profile contains the ordered setup/build commands and output path
used by `revyl build`.

Configure these build settings using the [Configuration](/cli/command-reference) page.

Expo dev-client hot reload needs a URL scheme baked into the native dev build. This is normally set as part of `revyl init`. The scheme is the custom URL prefix for your app, such as `myapp-dev://`. Revyl uses that scheme to open the Expo dev client on the cloud device and connect it to Metro.

If you use `app.json`, set `expo.scheme` before creating the dev build:

```json theme={null}
{
  "expo": {
    "scheme": "myapp-dev"
  }
}
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Build fails or times out">
    * Stream detailed diagnostics: `revyl build --profile development --platform ios --debug`
    * For an unattended remote EAS recipe, verify that `EXPO_TOKEN` is stored and referenced
    * Check EAS build credits only when the recipe uses EAS
    * Verify `package.json` dependencies
    * For EAS cloud builds, review the EAS dashboard logs
    * For EAS `--local` builds, review command output and logs in the local EAS working directory
    * Validate `eas.json`
  </Accordion>

  <Accordion title="Download links expired">
    * Artifacts expire after some time
    * Re-run build for fresh links
    * Download immediately after build
  </Accordion>

  <Accordion title="iOS or Android APK app won't install">
    * For iOS, ensure `simulator: true` is set in `eas.json`. For Android, ensure the profile builds an `apk`, not an `aab`.
  </Accordion>
</AccordionGroup>

## Resources

* [EAS Build Docs](https://docs.expo.dev/build/introduction/)
* [EAS Configuration](https://docs.expo.dev/build/eas-json/)
* [Development Builds](https://docs.expo.dev/development/introduction/)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.