DEV Community

Mason Roy
Mason Roy

Posted on

Shipping React Native Updates Without App Store Releases: A Practical Guide to OTA Updates

Building a React Native app is only half the job.

Once an app is in production, one of the biggest challenges is shipping fixes and improvements quickly without asking users to download a new version from the App Store or Google Play for every small change.

This is where Over-The-Air (OTA) updates become useful.

With OTA updates, JavaScript and other supported application assets can be delivered to users after the app has already been installed. This makes it possible to fix UI issues, update business logic, or release content changes without going through a complete store release process.

This article explains how OTA updates work in Expo/React Native, when to use them, and the important limitations developers should understand before relying on them in production.


Table of Contents


What Are OTA Updates?

OTA stands for Over-The-Air.

In a React Native application, a significant part of the application is written in JavaScript or TypeScript. That code is bundled and delivered with the application.

Normally, when you change that code, you create a new application build and submit it to the App Store or Google Play.

With OTA updates, supported JavaScript and asset changes can be distributed separately from the native application binary.

The general flow looks like this:

Developer
   |
   | Build & publish update
   v
Update Server
   |
   | Download
   v
User's React Native App
   |
   | Apply update
   v
New JavaScript Bundle
Enter fullscreen mode Exit fullscreen mode

This can significantly reduce the time between fixing an issue and getting that fix to users.


Why OTA Updates Matter

Imagine you discover a small production bug:

User opens Profile
        ↓
Profile screen crashes
        ↓
Bug is in JavaScript code
Enter fullscreen mode Exit fullscreen mode

Without OTA:

Fix bug
   ↓
Build application
   ↓
Submit to App Store / Play Store
   ↓
Review / rollout
   ↓
User downloads new version
Enter fullscreen mode Exit fullscreen mode

With OTA:

Fix bug
   ↓
Publish OTA update
   ↓
App downloads update
   ↓
User receives the fix
Enter fullscreen mode Exit fullscreen mode

The second workflow can be much faster.

OTA updates are particularly useful for:

  • JavaScript bug fixes
  • UI improvements
  • Business logic changes
  • Copy/content changes
  • Configuration changes supported by the application
  • Small feature improvements

However, OTA updates are not a replacement for native application releases.


How OTA Updates Work

An OTA system generally involves four important components:

┌────────────────────┐
│ Developer           │
│ Changes JS / Assets │
└─────────┬──────────┘
          │
          ▼
┌────────────────────┐
│ Update Service      │
│ Stores update       │
└─────────┬──────────┘
          │
          ▼
┌────────────────────┐
│ React Native App    │
│ Checks for update   │
└─────────┬──────────┘
          │
          ▼
┌────────────────────┐
│ Download + Apply    │
└────────────────────┘
Enter fullscreen mode Exit fullscreen mode

When the installed application starts, it can check whether an update compatible with the current native runtime is available.

If one exists, the application can download it and apply it according to the update strategy you've configured.

The important concept here is compatibility.

An OTA update still has to work with the native code already installed on the user's device.


OTA Updates With Expo

For Expo-based React Native applications, EAS Update provides a managed way to distribute updates.

The basic workflow is:

npx expo install expo-updates
Enter fullscreen mode Exit fullscreen mode

Then configure the project for EAS Update.

You can initialize EAS configuration with:

eas update:configure
Enter fullscreen mode Exit fullscreen mode

You will typically have an eas.json configuration describing your build profiles.

For example:

{
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal"
    },
    "preview": {
      "distribution": "internal"
    },
    "production": {}
  }
}
Enter fullscreen mode Exit fullscreen mode

The exact configuration depends on your project's build and release strategy.


Basic Setup

After configuring EAS Update, you can create an update using:

eas update
Enter fullscreen mode Exit fullscreen mode

You can also specify a branch:

eas update --branch production
Enter fullscreen mode Exit fullscreen mode

And provide a message describing the change:

eas update \
  --branch production \
  --message "Fix profile screen rendering issue"
Enter fullscreen mode Exit fullscreen mode

The update is then published to the configured update service.


Publishing an Update

A typical production workflow might look like this:

# Make your changes
git checkout -b fix/profile-rendering

# Test locally
npm start

# Commit your changes
git add .
git commit -m "fix: profile rendering"

# Publish OTA update
eas update --branch production --message "Fix profile rendering"
Enter fullscreen mode Exit fullscreen mode

The important distinction is that eas update publishes an update to the OTA service; it does not create a new App Store or Google Play binary.


Checking for Updates

You can also control update behavior inside your application using expo-updates.

For example:

import * as Updates from 'expo-updates';

async function checkForUpdates() {
  try {
    const update = await Updates.checkForUpdateAsync();

    if (update.isAvailable) {
      await Updates.fetchU
Enter fullscreen mode Exit fullscreen mode

Top comments (0)