RORK LABJP
PLAY — Google Play's target API level 36 requirement took effect yesterday, August 31. From today, new apps and updates must target Android 16VISIBILITY — Apps still on API 35 stay listed but disappear for users on newer Android versions. No error is raised; new installs simply fade, which makes the change easy to missEXTENSION — If you missed the deadline, an extension through November 1, 2026 can be requested in Play Console — best filed alongside a concrete migration planAPPLE — On the Apple side, the event lands September 9 and iOS 27 is reported to ship September 14. Testing generated apps on iOS 27 hardware before release week is time well spentEXPO — Expo released expo-paste-input on August 28, a native module that brings image, GIF, and sticker paste to React Native TextInputEAS — EAS Observe reached general availability on August 20, putting crash and performance monitoring on the same EAS platform as builds and updatesPLAY — Google Play's target API level 36 requirement took effect yesterday, August 31. From today, new apps and updates must target Android 16VISIBILITY — Apps still on API 35 stay listed but disappear for users on newer Android versions. No error is raised; new installs simply fade, which makes the change easy to missEXTENSION — If you missed the deadline, an extension through November 1, 2026 can be requested in Play Console — best filed alongside a concrete migration planAPPLE — On the Apple side, the event lands September 9 and iOS 27 is reported to ship September 14. Testing generated apps on iOS 27 hardware before release week is time well spentEXPO — Expo released expo-paste-input on August 28, a native module that brings image, GIF, and sticker paste to React Native TextInputEAS — EAS Observe reached general availability on August 20, putting crash and performance monitoring on the same EAS platform as builds and updates
Articles/Dev Tools
Dev Tools/2026-05-06Intermediate

Adding Expo Dev Client to Your Rork App

The moment you add react-native-mmkv or RevenueCat to a Rork app, Expo Go stops launching it. Here's how to set up Expo Dev Client (a custom development build) and the three pitfalls I've actually walked into.

Expo Dev ClientRork547React Native233Native Modules5Expo192EAS Build16Dev Environment2

You add react-native-mmkv to your Rork-generated app, and suddenly Expo Go won't open it anymore. After the splash screen you get a red screen that says "Native module cannot be null." That state.

This isn't a Rork or Expo bug. It's a deliberate design constraint: Expo Go can only run native modules that ship inside the Expo SDK. The minute your app pulls in a library that needs its own native code, Expo Go stops being useful. What you need next is Expo Dev Client — sometimes called a "custom development build."

This article walks through the exact steps to add Expo Dev Client to a Rork-generated app, plus the three places I've personally tripped. Once you've done it once, adding new native modules stops being painful.

Expo Go vs. Expo Dev Client — Get the Mental Model Right

These two are easy to confuse, so let me set the framing first.

Expo Go is a generic preview app that anyone can download from the App Store or Google Play. It runs your JavaScript and the native modules that come baked into the Expo SDK — but no third-party native modules.

Expo Dev Client is a development build of your specific app. The internals are essentially identical to your production binary, including all the third-party native modules. The only differences are that it can pull JavaScript from a Metro dev server at runtime and exposes the developer menu.

Think of Dev Client as "your production build with hot reload bolted on." Once you build and install it, JavaScript edits still flow through the normal reload loop.

Libraries That Force the Switch

Here are the libraries Rork users typically reach for that simply won't run in Expo Go:

  • react-native-mmkv — fast local storage
  • react-native-purchases (RevenueCat) — subscription billing
  • react-native-vision-camera — advanced camera
  • react-native-fast-image — optimized image caching
  • react-native-keychain — secure credential storage
  • @react-native-firebase/* — native Firebase SDKs
  • react-native-skia — advanced 2D graphics
  • react-native-onesignal — push notifications (see also Integrating OneSignal with Rork)

The moment any of these hit your package.json, you need a Dev Client. Conversely, as long as you're sticking to Expo SDK libraries (expo-image, expo-secure-store, expo-notifications, etc.), you can stay in Expo Go.

Step 1: Run Prebuild and Tidy Up app.json

The first step is Expo's prebuild command. It reads app.json and generates the native projects (ios/ and android/ directories).

# Run from your Rork project root
npx expo prebuild --clean

The --clean flag wipes any existing ios/ and android/ directories before regenerating. For a freshly Rork-generated project this is fine, but be careful if you've manually edited the native code.

After prebuild, expo.ios.bundleIdentifier and expo.android.package become required. Rork templates usually have them, but if not, add them like this:

{
  "expo": {
    "name": "MyRorkApp",
    "slug": "my-rork-app",
    "ios": {
      "bundleIdentifier": "com.yourcompany.myrorkapp"
    },
    "android": {
      "package": "com.yourcompany.myrorkapp"
    }
  }
}

By convention the bundle identifier is your domain reversed, and you want one that won't collide with anything reserved on App Store Connect. It's painful to change after launch, so pick the right one up front.

Step 2: Install expo-dev-client and Run an EAS Build

Next, install the Dev Client itself.

# Add the Dev Client library
npx expo install expo-dev-client
 
# Cloud build via EAS
npm install -g eas-cli
eas login
eas build:configure

eas build:configure is interactive and creates eas.json. If you've ever used EAS before, your existing config is fine.

Add a development profile to eas.json:

{
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "ios": {
        "simulator": true
      }
    },
    "preview": {
      "distribution": "internal"
    },
    "production": {}
  }
}

developmentClient: true is the flag that marks this as a Dev Client build. ios.simulator: true tells EAS to produce an iOS simulator binary. Drop that flag if you want to install on a physical device instead.

Now run the actual build:

# iOS simulator
eas build --profile development --platform ios
 
# Android — works for both physical devices and emulators
eas build --profile development --platform android

Because EAS builds in the cloud, you don't need a Mac to produce iOS builds. I work outside major cities and my Mac setup tends to lag, so this is the part I appreciate most. Builds usually finish in 10–20 minutes, and you'll get a download link by email and in the terminal.

Step 3: Launch Dev Client and Start Working

Install the Dev Client binary on your simulator or device, then start the dev server:

npx expo start --dev-client

The --dev-client flag matters. Without it you'll start the Expo Go-flavored dev server, which Dev Client can't connect to.

Scan the QR code with your Dev Client app, or press i (iOS) or a (Android) in the terminal to launch the simulator directly.

Once it connects, development feels normal. Save a file, see a reload, all of your native modules are available.

Three Pitfalls Worth Knowing About

1. Every New Native Module = Another Build

This is the most-misunderstood part of Dev Client. The build you produced with react-native-mmkv only contains react-native-mmkv. Add react-native-purchases later, and the new native module isn't in your Dev Client yet — you have to run eas build --profile development again.

JavaScript changes are still hot-reloaded. Native dependency changes mean a rebuild.

2. EAS Build Quotas and Pricing

EAS Build's free tier caps you at roughly 30 builds per month (as of May 2026). If you're juggling several solo apps, you'll hit that ceiling faster than you'd think. Budget for a paid plan from the start — the $19/month Production plan includes 2,000 build minutes.

When you're rapidly trying out native modules, local builds are also a real option:

eas build --profile development --platform ios --local

The --local flag runs the iOS build on your own Mac. You need Xcode set up, but you can iterate without burning the build quota.

3. The EAS Update Interaction

If you're already using EAS Update for OTA delivery, Dev Client needs its own channel configuration. Pin runtimeVersion in app.json and split channels between development and production builds:

{
  "expo": {
    "runtimeVersion": "1.0.0",
    "updates": {
      "url": "https://u.expo.dev/your-project-id",
      "requestHeaders": {
        "expo-channel-name": "development"
      }
    }
  }
}

Skip this and your Dev Client may pull stale JavaScript from the production channel — meaning the bug "you just fixed locally" appears to come back. I lost half a day to exactly this once.

Why Rork Users Should Care Specifically

Rork's AI-generated code is designed to stay within the Expo SDK by default. That's a deliberate call so beginners can run an app instantly in Expo Go — and it's the right one for that audience.

But once you're seriously aiming at a release, the Dev Client transition becomes basically inevitable. Advanced push notifications, in-app subscriptions, fast key-value storage — they all involve native modules.

I've personally hit this wall about three times on the way to shipping a Rork-generated app to the App Store. Early on I'd assume "the AI's code is broken" and ask Rork to retry. The real cause was always environmental. The first time someone explained Dev Client to me, my honest reaction was "I wish I'd known sooner."

So when you start thinking about going to production, plan to migrate to Dev Client at the same time. The articles on App Store submission with Fastlane and EAS and picking a local storage strategy both assume Dev Client, so reading them in sequence cuts down the surprises.

A Quick Sanity Check When Things Break

Even with all of this in place, you can still hit a state where the app launches but immediately crashes. Before diving deep, run through these four questions in order:

  • Did you actually rebuild after adding the new native module? eas build --profile development --platform ios|android
  • Is the Dev Client you installed the latest one? Old binaries linger in simulators and emulators.
  • Is the dev server running with --dev-client, not the default Expo Go URL?
  • If you use EAS Update, are you on the right channel for this build?

About 90% of my own Dev Client failures fall into one of those four buckets. Working through them takes a couple of minutes and saves hours of guessing.

Next Step

You've got Dev Client running. The next move is to add exactly one native module that your app actually needs and build it. Start small — react-native-mmkv is a good first target because it has minimal side effects. Once that flow feels smooth, scale up to RevenueCat, push notifications, or whichever heavyweight library you actually need.

Once Dev Client is in place, your day-to-day development changes for the better. You keep Rork's speed while gaining access to the entire React Native ecosystem — that's the whole point.

Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $15 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Dev Tools2026-05-02
Adding Native Modules to Rork-Generated Apps: A Practical Guide to Expo Prebuild
When your Rork prototype needs a native SDK or custom module, Expo Prebuild is the bridge to production. This practical guide walks through the limits of Managed Workflow and the actual commands for moving toward Bare Workflow.
Dev Tools2026-08-22
Every bulk replace exited zero. The damage was in the lines I did not delete
Run a bulk replace over generated code and the breakage lands on the neighbouring lines, not the matched ones. Here is what broke in a live project, and a dependency-free guard that checks the invariants a replace must preserve.
Dev Tools2026-08-20
A beta-SDK build can reach TestFlight, but it can't reach review
Builds made with a beta Xcode can be distributed through TestFlight, but they cannot be submitted for App Store review. Here is how to check which SDK produced your build, and how to protect your release profile in eas.json.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →