Export web project for deployment
To deploy a web app, create a static build by exporting your web project to a dist directory using one of: `npx expo export --platform web`, `yarn expo export --platform web`, `pnpm expo export --platform web`, or `bun expo export --platform web`. Re-run this command every time before deploying when you make changes to your web app.
Initial web deployment with EAS CLI
To publish your web app, run `eas deploy`. On the first run, you'll be prompted to select a preview subdomain for your project. This subdomain is a prefix used to create a preview URL and is used for production deployments. For example, in `https://test-app--1234.expo.app`, `test-app` is the preview subdomain. After deployment completes, the EAS CLI outputs a preview URL to access the deployed app.
Production web deployment
To create a production deployment, run `eas deploy --prod`. Once your deployment is complete, the EAS CLI outputs a production URL to access your deployed app.
Prerequisite: expo.web.output configuration
In your project's app.json, ensure that the `expo.web.output` property is either `static` or `server` before deploying your web app with EAS Hosting.
Automatic web deployment with EAS Workflows
You can automatically deploy your app to the web using EAS Workflows. Create a file named `.eas/workflows/deploy-web.yml` at the root of your project. A workflow that deploys on every commit to the `main` branch would contain: name 'Deploy web', on push with branches `['main']`, jobs with deploy_web name 'Deploy web', type 'deploy', and params `prod: true`. You can manually run the workflow with `eas workflow:run deploy-web.yml`.
qr.expo.dev format=url parameter returns plain text URL instead of SVG
Adding format=url to the query parameters requests the URL directly as plain text instead of the default SVG QR code image. This is useful when sharing the URL is more convenient than sharing the QR code.
qr.expo.dev query parameters for update by device traits
To emulate preview and production builds that make requests with runtimeVersion and channel properties, use these required query parameters:
| Parameter | Required | Description |
|-----------|----------|-------------|
| `projectId` | Yes | The ID of the project. |
| `runtimeVersion` | Yes | The runtime version of the build. |
| `channel` | Yes | The channel name of the build. |
Example: https://qr.expo.dev/eas-update?projectId=your-project-id&runtimeVersion=your-runtime-version&channel=your-channel
QR code from qr.expo.dev deep links into development build
The QR code generated by qr.expo.dev represents a deep link URL with the pattern exp+{slug}://expo-development-client/?url=https://u.expo.dev/{projectId}?runtime-version={runtimeVersion}&channel-name={channel}. This URL deep links into a development build and instructs it to fetch the latest update on the specified channel.
qr.expo.dev cloud function generates Expo-branded QR codes
qr.expo.dev is a cloud function that generates Expo-branded QR codes. This function creates QR codes for EAS Update, which are used to preview updates in development builds and Expo Go.
qr.expo.dev /eas-update endpoint for generating QR codes
The /eas-update endpoint generates QR codes that deep link into a development build and instruct it to fetch the latest update on a specified channel. The base URL pattern is https://qr.expo.dev/eas-update with query parameters.
qr.expo.dev base query parameters
Base query parameters for /eas-update endpoint:
| Parameter | Required | Default | Description |
|-----------|----------|---------|-------------|
| `slug` | No | exp | Use slug from app config to target a development build. Use 'exp' to target Expo Go. |
| `appScheme` | No | exp | Deprecated, replaced by slug. |
| `host` | No | u.expo.dev | The hostname of the server that handles update requests. |
| `format` | No | svg | Response format: svg (default) or url (plain text URL). |
Automatic preview publishing with EAS Workflows
You can create previews automatically on every commit using EAS Workflows. Create a file at .eas/workflows/publish-preview-update.yml with the workflow configuration. The example configuration publishes an update on every commit to every branch, using 'name: Publish preview update', 'type: update', and trigger 'on: push: branches: ["*"]'. The branch parameter is set to '${{ github.ref_name || "test" }}'.
eas update --auto command publishes preview to current branch
Running 'eas update --auto' publishes an update under the current branch name, allowing you to share a preview of your changes with your team.
EAS Dashboard link shows published update with QR code
After publishing an update with 'eas update --auto', the terminal shows an EAS Dashboard URL to the published update. Reviewers can open this link, click the Preview button, and scan the QR code displayed to open the preview on their device.
eas workflow:run command manually triggers workflow
You can manually run a workflow with the EAS CLI command 'eas workflow:run publish-preview-update.yml'.
EAS Update compatibility with development builds
EAS Update works with development builds as long as the update is compatible with the installed build, with compatibility determined by runtime versions.
Expo Orbit app download and installation
Expo Orbit is a macOS, Windows, and Linux app designed to speed up installing and running builds from EAS. You can download it directly from GitHub releases or use an alternative installation method.
Expo Orbit sign-in requirement
After installing the Orbit app, you must sign in to your Expo account from Settings.
Expo Orbit automatic update installation matching
When you launch an update with Orbit, it looks for the latest development build that matches both the runtime version and target platform of the update. If a compatible build is found, the update installs automatically on the target device and launches with a deep link pointing to the update.
Expo Orbit fallback when no compatible build is available
If no compatible development builds are available (expired, not created, EAS Build not used, or building locally), Orbit prompts you to proceed. You can click 'Launch with deep link' to open the update if you already have a compatible development build installed on your target device.
Expo Orbit update preview platform support
Launching updates with Expo Orbit is not supported on physical iOS devices. It is supported on Android devices and emulators, and iOS Simulators.
How to preview an update with Expo Orbit
To preview an update with Expo Orbit: (1) Navigate to your project's Updates tab, (2) Select the update you want to preview, (3) Click Preview to open the Preview dialog, (4) Under Open with Orbit, select a platform to launch the update, (5) Orbit will install and launch the update on the selected Android Emulator or iOS Simulator.
Prerequisite to preview updates with Expo Orbit
Previewing with Expo Orbit requires you to have an update already published. You must publish an update before you can preview it.
EAS Update channel in eas.json
Running eas update:configure adds a channel field to each build profile in eas.json. This channel is embedded in the native build and used to deliver over-the-air updates to devices running that build.
PR preview workflow with EAS Update
Create pr-preview.yml with on.pull_request trigger on branches: ['*']. Use type: update job to publish updates on PR, and type: github-comment job to post a comment on the pull request with a link or QR code to test the update. The comment job does not require explicit configuration—it automatically posts the update link after the update job succeeds.
PR preview workflow example
Example pr-preview.yml workflow that publishes updates on pull requests and comments with the update link:
name: PR Preview
on:
pull_request:
branches: ['*']
jobs:
publish_preview:
name: Publish PR preview update
type: update
environment: preview
params:
channel: preview
comment:
needs: [publish_preview]
type: github-comment
PR preview uses EAS Update for deployment
PR previews use EAS Update to deliver JavaScript bundle changes to devices that already have a compatible preview build installed, skipping native compilation. This allows reviewers to open and test changes quickly by opening a link or scanning a QR code posted in the PR comment.
Update jobs trigger OTA updates when no native changes detected
Add update jobs with type: update to publish over-the-air updates when only TypeScript/JavaScript files changed. Use if: ${{ needs.get_android_build.outputs.build_id }} on update jobs so they run only when an existing build was found (no new native build created). Update jobs require branch: production and platform parameters.
EAS Hosting overview and deploy job
EAS Hosting is a service for hosting and deploying web builds of an Expo app. Each deployment gets its own unique URL, and a project has a single production URL that serves whatever was last deployed to production. The `deploy` pre-packaged job in EAS Workflows runs the web export, uploads the output to EAS Hosting, and returns the deployment URL as the job output.
Workflow files read from default branch
EAS Workflows reads workflow files from the default branch of the repository. Changes to workflow files must be committed and pushed to the default branch (typically `main`) to become effective.
Test preview workflow manually
To manually run the preview workflow, use the command: `eas workflow:run .eas/workflows/preview.yml`. On the EAS dashboard, the preview workflow run shows the `deploy_web` job running in parallel with build jobs. Click the **View Deployment** link under the **Deploy web (preview)** job to open the deployed web build in the browser.
deploy job parameters
The deploy job has two optional parameters: `prod` (boolean) - if true, deploys to the project's production URL; if omitted, deploys as a preview. `alias` (string) - names a stable alias URL like `awesome-project--staging.expo.app`.
Configure web.output for static export
To export a static web build, set the `web.output` field to `static` in app.json under the `expo` object. The `static` value tells the Expo CLI to produce a directory of static HTML, JavaScript, and asset files that EAS Hosting can serve. Expo also supports `single` and `server` output modes, but `static` produces plain files that any host can serve.
app.json configuration for static web output
Example configuration in app.json to enable static web export:
```json
{
"expo": {
"web": {
"output": "static"
}
}
}
```
Preview deployment web URL format
When deploying a web preview without the `prod` parameter, each push gets a unique URL in the format `https://awesome-project--abc123.expo.app`.
Add deploy_web job to preview workflow
To deploy web builds in a preview workflow, add a `deploy_web` job to **.eas/workflows/preview.yml**. This job runs in parallel with existing build jobs because it has no `needs` dependency. Without a `prod` parameter, it deploys as a non-production version with unique per-deployment URLs.
Preview workflow deploy_web job example
```yaml
name: Preview builds
jobs:
# ... existing fingerprint, get-build, build_android, build_ios, notify jobs
deploy_web:
name: Deploy web (preview)
type: deploy
```
Production deployment with prod parameter
To deploy web to the production URL, add a `deploy_web` job to **.eas/workflows/production.yml** with `params.prod: true`. This deploys the web app to the production URL like `https://awesome-project.expo.app`.
Production workflow deploy_web job example
```yaml
name: Deploy to production
on:
push:
tags: ['v*.*.*']
jobs:
# ... existing fingerprint, get-build, build, update jobs ...
deploy_web:
name: Deploy web (production)
type: deploy
params:
prod: true
```
The `['v*.*.*']` pattern matches strict three-part semantic versions. The `params.prod: true` deploys to the production URL.
GitHub Actions integration with EAS Update
The GitHub Actions guide covers automating publishing of updates with EAS Update using GitHub Actions.
EAS Update for publishing and customizable strategies
EAS Update documentation covers publishing updates and applying customizable strategies.
Install expo-updates library for EAS Update
To use EAS Update, install the expo-updates library using the appropriate package manager: npm (npx expo install expo-updates), yarn (yarn expo install expo-updates), pnpm (pnpm expo install expo-updates), or bun (bun expo install expo-updates).
EAS Update allows non-native code updates between app store releases
EAS Update enables developers to push updates for JavaScript code, styling, and images without going through app store releases. This allows sharing changes with team members for testing between official releases.
app.config.js requires updates and runtimeVersion properties for EAS Update
When using a dynamic app.config.js file, the updates and runtimeVersion properties must be added to make the project compatible with EAS Update. Run 'eas update:configure' to obtain these properties and their values from EAS, then manually copy them to app.config.js.
eas update:configure handles setup differently for app.json vs app.config.js
For projects using app.json (non-dynamic config), the 'eas update:configure' command automatically configures the app and adds the required properties directly to app.json and eas.json. For dynamic app.config.js projects, manual copying is required after obtaining values from EAS.
Add channel property to build profiles in eas.json
Each build profile in eas.json should have a channel property added. The eas update:configure command adds this automatically. For example, development profile gets 'channel: development', preview gets 'channel: preview', and production gets 'channel: production'. Profiles that extend other profiles (like ios-simulator extending development) can have their redundant channel removed.
Channels group builds together for targeted updates
Channels are used to group builds by platform and purpose. For example, both Android and iOS production builds can share a 'production' channel. When publishing an update to a specific channel, EAS Update targets all builds associated with that channel, enabling platform-agnostic update distribution.
Create new development build after adding expo-updates
A new development build must be created with 'eas build --platform android --profile development' (or other platforms) after installing expo-updates, since the previous build does not contain the library. This new build must be installed on a device before testing updates.
Publish update with eas update command using channel
Use 'eas update --channel <channel-name> --message "<message>"' to publish an update. The channel determines which builds receive the update. For example, 'eas update --channel development --message "Change first button label"' publishes to all development channel builds.
Channels map to git branches automatically
When an EAS Update channel is created, it is automatically mapped to a git branch with the same name. This allows teams to manage updates similarly to how they manage code branches.
Non-development builds auto-download updates on app startup
Updates for preview or production builds are automatically downloaded when the app starts and makes a request for new updates. Team members running preview or production builds will receive updates without requiring manual intervention.
Force close and reopen app twice to download preview/production updates
To test updates on preview or production builds, the app must be force closed and reopened twice. The first reopening triggers the download, and the second reopening applies the update.
EAS Update is for OTA (over-the-air) updates
EAS Update has two meanings: (1) The cloud hosting service from EAS used for OTA updates; (2) The CLI command `eas update` from EAS CLI used to publish static files to the cloud hosting service.
EAS Hosting for web apps with Expo Router and React Native Web
EAS Hosting is a cloud service from EAS for quickly deploying web projects built using Expo Router and React Native Web.
qr.expo.dev query parameters for EAS updates
To create a QR code that returns the latest update available, use qr.expo.dev/eas-update with one of these two methods:
**Query by Channel ID:**
Returns the latest update available on the branch or branches mapped to that channel.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `projectId` | Yes | The ID of the project. |
| `channelId` | Yes | The ID of the channel. |
Example: https://qr.expo.dev/eas-update?projectId=your-project-id&channelId=your-channel-id
**Query by Branch ID:**
Returns the latest update available on that branch.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `projectId` | Yes | The ID of the project. |
| `branchId` | Yes | The ID of the branch. |
Example: https://qr.expo.dev/eas-update?projectId=your-project-id&branchId=your-branch-id
qr.expo.dev query parameters for EAS updates
To create a QR code for an EAS update, use qr.expo.dev/eas-update with one of these parameter combinations:
**Option 1: By update group ID**
Use these parameters to create a QR code for an update group:
| Parameter | Required | Description |
|-----------|----------|-------------|
| `projectId` | Yes | The ID of the project. |
| `groupId` | Yes | The ID of the update group. |
Example: https://qr.expo.dev/eas-update?projectId=your-project-id&groupId=your-update-id
**Option 2: By platform-specific update ID**
Use this parameter to create a QR code for a specific update:
| Parameter | Required | Description |
|-----------|----------|-------------|
| `updateId` | Yes | The ID of the update. |
Example: https://qr.expo.dev/eas-update?updateId=your-update-id