Documentation

React Native

Add replicate-interceptor-rn to your React Native app to enable recording and intercept mode.

Note: ReplicateInterceptor.init() is a no-op in release builds. Safe to leave in your production code.

Installation #

View it on npm.

bash
npm install replicate-interceptor-rn
cd ios && pod install

Setup #

init() must be called before AppRegistry.registerComponent. Place it at the very top of index.js, before any other imports that make network calls:

javascript
// index.js — must be the very first lines
import {{ ReplicateInterceptor }} from 'replicate-interceptor-rn';

(async () => {{
  await ReplicateInterceptor.init();
  AppRegistry.registerComponent(appName, () => App);
}})();
Important: AppRegistry.registerComponent must be called synchronously after init() resolves. React Native's runApplication is called immediately after the bundle loads and does not wait for async work.

What it intercepts automatically #

The interceptor patches global.XMLHttpRequest once during init(). This automatically covers:

  • fetch — built on XHR in React Native
  • axios — uses XHR under the hood in React Native. No patchAxios() call required.
  • Any library built on XMLHttpRequest — covered automatically, no additional configuration

Debug-only mode #

By default, init() activates on the iOS Simulator in both Debug and Release builds, letting you share .replica files with teammates who don't need Metro running.

If you want to restrict the interceptor to debug builds only, pass devOnly: true:

javascript
await ReplicateInterceptor.init({ devOnly: true });

When devOnly: true, the interceptor skips activation in Release builds. The Replicate app detects this and shows an orange warning banner on any snapshot recorded this way. Clicking the banner opens the Metro not running section of these docs with instructions for recipients.

Option Activates in Can share .replica without Metro?
init() Debug + Release (simulator only) Yes
init({ devOnly: true }) Debug only No — recipient must run a debug build with Metro

Keystore (react-native-keychain) #

Keystore capture requires react-native-keychain as a peer dependency:

bash
npm install react-native-keychain

If react-native-keychain is not installed, keystore capture is silently skipped. Everything else works normally.

The React Native keystore format stores service/username/password triples (matching react-native-keychain's data model):

json
{
  "entries": [
    {{
      "service": "com.example.app",
      "username": "user@example.com",
      "password": "eyJhbGci..."
    }}
  ],
  "exportedAt": "2026-01-01T00:00:00Z"
}
Format difference: Flutter keystores use a flat key–value map. React Native keystores use this array format. The two formats are not interchangeable — a .replica recorded from a Flutter app cannot have its keystore restored into a React Native app, and vice versa.

Known limitations #

The following are not intercepted:

  • WebSockets — not captured
  • Native HTTP modules that bypass JavaScript — some analytics SDKs, some payment SDKs, and background upload libraries make requests in Swift/Java native code and are not captured
  • gRPC over HTTP/2 — not captured

These limitations affect a small minority of network calls in typical React Native apps. REST APIs over fetch or axios are fully covered.

Troubleshooting #

Symptom Solution
Axios calls not captured Axios uses XHR in React Native and is captured automatically. If calls are missing, confirm that init() is called before any axios imports execute at module level.
init() must be first Any network call that happens before init() resolves will not be captured. Place init() at the very top of index.js.
Works in debug but not release Expected — the interceptor is a no-op in release builds by design.
Keystore not captured Install react-native-keychain as a peer dependency. Without it, keystore capture is silently skipped.
Expo managed workflow Not supported. The plugin requires custom native modules which are not available in Expo managed workflow. Use bare workflow.

Opening the app without Metro running

If you see the debug-only mode warning banner on a snapshot in Replicate, it was recorded with
init({ devOnly: true }). Recipients need Metro running to restore it. You have two options:

  • Run a debug build with Metro — start Metro (npx react-native start), then open the app from the simulator.
  • Re-record without devOnly — change your call to init() (no options) and record a new snapshot. It will work in both Debug and Release builds.

If you install the app with npx react-native run-ios and then stop the process, reopening the app from the simulator will show a blank screen or a bundle connection error. The debug build does not embed the JS bundle — it expects Metro to be running and serving it live.

Build in Release mode instead. This embeds the JS bundle directly into the app so it runs standalone, with no Metro required:

npx react-native run-ios --mode Release
Note: Release mode is also the correct environment for testing the Replicate interceptor — in production, Metro will not be present, so testing without it gives you the most realistic behaviour.