Managing production, preview, and runtimeVersion after introducing EAS Update

작성자

카테고리:

← 피드로
DEV Community · hiro@ · 2026-08-06 개발(SW)

hiro@

This article is an English translation of the original Japanese article.

I introduced EAS Update to an Expo app so that JavaScript and image changes could be delivered without store review. However, just getting the command to run is not enough for safe operation. You need channel and runtimeVersion to decide which builds receive updates.

Currently, I use three channels (development, preview, production) combined with the appVersion policy.

Fix channel to build profile

In eas.json, each build sets the target API and channel.

{
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "channel": "development",
      "env": {
        "APP_ENV": "development",
        "EXPO_PUBLIC_API_URL": "https://dev.squad-note.com"
      }
    },
    "preview": {
      "distribution": "internal",
      "channel": "preview",
      "env": {
        "APP_ENV": "production",
        "EXPO_PUBLIC_API_URL": "https://squad-note.com"
      }
    },
    "production": {
      "autoIncrement": true,
      "channel": "production"
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

Preview is an internal distribution build using the production API. You can verify OTA updates under the same data conditions before releasing to production. Development connects to the dev API, so its purpose differs from preview.

runtimeVersion matches appVersion

Expo config has this setting:

updates: {
  url: "https://u.expo.dev/<project-id>",
  fallbackToCacheTimeout: 0,
},
runtimeVersion: {
  policy: "appVersion",
},

Enter fullscreen mode Exit fullscreen mode

If the app version is 1.0.11, only updates published for that runtime will be delivered. This setting makes it harder to mistakenly deliver new JavaScript to old binaries with different native configurations.

With fallbackToCacheTimeout: 0, the app does not wait indefinitely for updates at launch. Updates are applied at the next launch.

Changes delivered OTA versus changes sent to stores

Only changes that are complete with JavaScript and assets should be published as production updates.

cd apps/mobile
eas update --channel preview --message "Fix date display"
eas update --channel production --message "Fix date display"

Enter fullscreen mode Exit fullscreen mode

The following changes require new binaries:

  • Adding or updating native libraries
  • Changes to plugins, ios, or android settings in app.config.ts
  • Expo SDK updates
  • App version changes that affect runtimeVersion

I do not decide that all dependency changes are OTA-incompatible. Instead, I check whether the package includes native code. If unclear, I route it through a normal build.

Actual release order

For routine fixes, I follow this sequence:

  1. Verify locally and in Expo Go or development build
  2. Publish to preview channel
  3. Restart internal distribution build and verify
  4. Publish the same change to production channel
  5. For the next native change, increment version and submit to store

EAS Update speeds up releases but does not eliminate store builds. Channel is the delivery target, runtimeVersion is the compatibility boundary. After defining these two as separate roles, I integrated the update command into operations.

References

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다