Secure Communication Between Isolated React Native Instances

Authors
Aliaksandr Babrykovich
Senior C++ Engineer
@
Callstack

In our previous article, we introduced react-native-sandbox - a library that enables running multiple, isolated React Native instances within a single application. While the initial release focused on host-sandbox communication, we've now added a powerful new feature: direct communication between sandbox instances.

This enhancement opens up new possibilities for building complex multi-instance applications where sandboxes can communicate directly with each other, bypassing the host application entirely, while still maintaining the security.

Understanding Communication Patterns

Before diving into the implementation, let's clarify the two communication patterns available in react-native-sandbox:

Sandbox-Host-Sandbox - The Old Approach

This was the only way sandboxes could communicate with each other - through the host application acting as a message dispatcher. This approach came with performance penalties and unnecessary boilerplate code.

This is the traditional communication pattern where sandboxes communicate through the host application:

Sandbox A → Host → Sandbox B

Implementation:

const handleMessage = (data: any) => {
// Boilerplate routing logic that grows with each sandbox
  if (data.target === 'sandbox-b') {
    sandboxBRef.current?.postMessage(data.payload);
  } else if (data.target === 'sandbox-c') {
    sandboxCRef.current?.postMessage(data.payload);
  } else if (data.target === 'sandbox-d') {
    sandboxDRef.current?.postMessage(data.payload);
  }
// ... more boilerplate for each additional sandbox
};

<SandboxReactNativeView
  ref={sandboxARef}
  onMessage={handleMessage}
/>

<SandboxReactNativeView
  ref={sandboxBRef}
  onMessage={handleMessage}
/>

<SandboxReactNativeView
  ref={sandboxCRef}
  onMessage={handleMessage}
/>

// ... more sandboxes = more boilerplate

This approach required constant maintenance of routing logic in the host application and created tight coupling between sandboxes and the host's message handling implementation.

Sandbox-Sandbox - The New Approach

Sandboxes can now communicate directly with each other, eliminating the host-as-dispatcher pattern and all its associated problems.

This is the new direct communication pattern where sandboxes communicate directly:

Sandbox A ↔ Sandbox B

Implementation:

// Host application - NO message routing needed!export default
function App() {
  return (
    <View style={styles.flexRow}>
      <View style={styles.flex10Margin}>
        <SandboxReactNativeView
          origin="A"
          jsBundleSource="sandbox"
          componentName="SandboxA"
          allowedOrigins={['B']} // Simple configuration
        />
      </View>

      <View style={styles.flex10Margin}>
        <SandboxReactNativeView
          origin="B"
          jsBundleSource="sandbox"
          componentName="SandboxB"
          allowedOrigins={['A']} // Simple configuration
        />
      </View>
    </View>
  );
}

// Sandbox A - Direct communication
const sendToB = () => {
  globalThis.postMessage({ type: 'increment', value: 1 }, 'B');
};

// Sandbox B - Direct communication
const sendToA = () => {
  globalThis.postMessage({ type: 'decrement', value: 1 }, 'A');
};

With direct communication, sandboxes can send messages to each other without any involvement from the host. There’s no need for routing logic, no extra boilerplate, and no changes required in the host when adding new sandboxes. Just set the allowedOrigins prop, and sandboxes can communicate directly and efficiently.

Security Model

Communication maintains the same security principles as the rest of react-native-sandbox:

Origin-Based Access Control

Each sandbox explicitly declares which other sandboxes can send messages to it through the allowedOrigins prop:

// Sandbox A allows messages from Sandbox B
allowedOrigins={['B']}

// Sandbox B allows messages from Sandbox A
allowedOrigins={['A']}

Bidirectional Control

Communication is not automatically bidirectional. If Sandbox A wants to send messages to Sandbox B, both conditions must be met:

  1. Sandbox A's allowedOrigins includes 'B' (to send)
  2. Sandbox B's allowedOrigins includes 'A' (to receive)

Dynamic Permissions

The allowedOrigins can be updated at runtime, allowing for dynamic permission management:

const [allowCommunication, setAllowCommunication] = useState(false);

<SandboxReactNativeView
  origin="A"
  allowedOrigins={allowCommunication ? ['B'] : []}
  // ... other props
/>

Demo time

Check out the p2p-counter example, which demonstrates two sandboxes updating each other's state directly, no host routing required.

Conclusion

Direct communication between React Native sandbox instances represents a significant evolution in the react-native-sandbox library. It provides developers with the flexibility to build complex, multi-instance applications with direct communication capabilities while maintaining the security and isolation benefits that make sandboxing valuable.

Whether you're building a micro-frontend dashboard, or a plugin system, direct sandbox communication enables new architectural patterns that were previously difficult to achieve with React Native.

To get started with direct sandbox communication, check out the p2p-counter example and the complete API documentation.

Ready to build secure, scalable multi-instance applications?

Get started with react-native-sandbox

‍

Insights

Learn more about Security

cover

Dec 17Podcast

A (Secure) Christmas Carol: The Story of Npmezer Scrooge

A holiday story about npm audits, unpinned dependencies, and the real cost of ignoring JavaScript security warnings.

cover

May 13Article

React Native Legal: Zero-Config OSS License Screens for Your App

Add license acknowledgments to your React Native app with ease using React Native Legal-a zero-config tool for OSS compliance across iOS, Android, tvOS, and AndroidTV platforms.

cover

Jul 3Podcast

Authorization: Security Deep-Dive With Okta (Part 2)

Let's talk access control, delegated authorization, and more. Learn modern security frameworks and get tips for creating reliable apps.

cover

Jul 2Podcast

Authentication: Security Deep-Dive With Okta (Part 1)

Join us as we discuss authentication's past, present, and future. From MFA to passkeys, learn how to enhance security and efficiency in your applications.

cover

Mar 8Article

Learn Once, Hack Everywhere

Demystify reverse engineering of mobile apps, dive into tools, analyze .apk files, and secure React Native code with our article.

cover

Feb 21Article

SSL Pinning in React Native Apps

Learn to implement SSL pinning to future-proof your React Native app against security attacks. Dig deeper into native SSL implementations for iOS & Android.

cover

Oct 28Article

Stripe Identity: ID Authentication Made Simple

Learn about preventing fraud with Stripe Identity React Native SDK.

cover

Nov 21Article

Secure Your React Native app

Learn how to make your React Native app as secure fot your application and customers.

cover

Mar 19Tutorial

The Hard Way vs. The React Native AI SDK Way: Stop Writing Custom Modules for Every Model

Learn how React Native AI uses a unified provider model to switch between cloud and on-device LLMs without rewriting application logic, enabling reliable AI experiences online and offline.

cover

Mar 12Tutorial

Build Smarter Apps: Tool Calling & AI Orchestration Explained

Learn how on-device models in React Native can call tools, interact with external APIs, and return structured outputs you can use directly in application logic.

cover

Mar 5Tutorial

MLC LLM + React Native: On-Device AI Without the Pain

Learn how to run third-party on-device LLMs in React Native using MLC LLM. Choose your models, run them efficiently across platforms, and keep a unified JavaScript API with React Native AI.

cover

Feb 24Tutorial

Intelligent Fallbacks with Apple Intelligence in React Native

Learn how to use Apple’s built-in Foundation Models in React Native apps, reduce memory usage, and enable fast, fully on-device AI with React Native AI Apple.

cover

Feb 10Tutorial

What Is the React Native AI SDK? A Complete Intro & Quickstart

Learn why on-device AI matters for React Native apps, how local LLMs behave offline, and what problems React Native AI is designed to solve from day one.

cover

Jan 29Tutorial

Implementing an Android TurboModule with Kotlin

Learn how to implement a React Native TurboModule on Android, from the TypeScript spec and Codegen to the Kotlin implementation and package registration.

cover

Jan 19Tutorial

Working with Different Threads in Swift TurboModules

Learn how JavaScript, native module, background, and main threads interact in React Native TurboModules, and how to use GCD queues to run async work safely in Swift.

cover

Jan 9Tutorial

How to Add Type-Safe Constants to Swift TurboModules

Learn how to expose typed, immutable constants from a Swift TurboModule using Codegen, and get full end-to-end type safety between native and JavaScript.

cover

Dec 30Tutorial

Adding Event Emitters to Your TurboModule in Swift

Learn how to emit native events from a Swift TurboModule and subscribe to them in JavaScript, including proper memory management and Codegen integration.

cover

Dec 22Tutorial

Writing Your First TurboModule in Swift

Learn how to build a fully working TurboModule in Swift, integrate it with Codegen, and bridge it through Objective‑C inside an Expo app.