Skip to content

Commit c6fec73

Browse files
committed
docs: add article.md
1 parent 8ec0143 commit c6fec73

4 files changed

Lines changed: 135 additions & 0 deletions

File tree

docs/article.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# React Native Inception: When One App Just Isn't Enough
2+
3+
## Intro
4+
5+
Six years ago, a brave soul ventured into the depths of r/reactjs and asked the forbidden question: ["How to embed a React Native app inside another React Native app?"](https://www.reddit.com/r/reactjs/comments/d9flm6/how_to_embed_a_react_native_app_inside_another/)
6+
7+
The response was... well, let's just say the React community wasn't exactly bursting with enthusiasm. With a whopping 3 upvotes and few comments that can be summarized as: "Why would you even want to do that?"
8+
9+
And that was it. Case closed. The post quietly disappeared into the digital abyss where brave but unpopular ideas go to die... or not!
10+
11+
![Hold my beer meme](./images/hold-my-beer.png)
12+
13+
Well, sometimes the "easier way around" is actually the boring way around, and where's the engineering joy in doing things the sensible way? I'm here to tell you that there **actually is a place for this idea**, and the `react-native-sandbox` package is here to prove it.
14+
15+
What if I told you that you *can* actually run React Native inside React Native? Not with WebViews (ew), not with some hacky iframe solution, but with actual, honest-to-goodness React Native components rendering other React Native components in isolated JavaScript contexts?
16+
17+
Yes, this is the story of how we took the concept of "nested apps" and made it so meta that even Christopher Nolan would be envious.
18+
19+
![Yo Dawg meme](./images/yo-dawg.png)
20+
21+
So we put React Native in your React Native so you can render components while you render components! It's like when someone first figured out you could run a virtual machine inside a virtual machine.
22+
23+
## But Actually, This Makes Sense
24+
25+
Okay, jokes aside—let's talk about why you might actually want to run React Native inside React Native (and why it's not just a meme experiment gone rogue).
26+
27+
Picture this: you’re building a platform where different features, plugins, or even entire mini-apps need to run in isolation, possibly developed by different teams, delivered on different schedules, and with different dependencies. This is where `react-native-sandbox` shines:
28+
29+
- **True Isolation**: Each plugin or tenant runs in its own React Native instance, with its own JavaScript context and native module access. No more global namespace collisions or dependency hell.
30+
- **Independent Delivery**: Teams can ship, update, or roll back their features independently, without waiting for a monolithic app release cycle.
31+
- **Team Autonomy**: Different teams (or even external partners) can work on their own plugins, using their own toolchains, dependencies, and release cadences.
32+
- **Crash Containment**: If one plugin crashes, it doesn’t take down the whole app—just that isolated instance.
33+
- **Security & Permissions**: You can restrict which native modules or APIs each plugin can access, reducing the blast radius of bugs or vulnerabilities.
34+
- **A/B Testing & Experiments**: Easily swap in and out different plugin versions for different users, without risking the stability of the main app.
35+
- **Legacy & Migration**: Run old and new code side by side, or gradually migrate legacy features to new architectures without a big-bang rewrite.
36+
37+
What started as a joke is actually a powerful tool for building more modular, flexible, and future-proof React Native apps. Sometimes, the wild ideas are the ones that move the platform forward.
38+
39+
## What is `react-native-sandbox`
40+
41+
`react-native-sandbox` is a React Native component and native module that allows you to run multiple, fully isolated React Native instances side by side within a single app. Each instance runs its own JavaScript bundle, maintains its own state, and can be configured with a specific set of allowed native modules (TurboModules).
42+
43+
Key features:
44+
- **Isolation**: Each sandboxed instance has its own JavaScript runtime and native bridge, preventing interference between plugins or tenants.
45+
- **Configurable Permissions**: You can specify which native modules are accessible to each instance, improving security and stability.
46+
- **Communication through a safe API**: Instances can communicate with the host app via a controlled, message-passing API that enforces boundaries and prevents unsafe interactions.
47+
- **Flexible Integration**: Use cases include plugin systems, micro-frontends, multi-tenant apps, and gradual migration of legacy code.
48+
49+
In short, react-native-sandbox provides a robust foundation for building modular, extensible, and independently upgradable features within a single React Native application.
50+
51+
On API level you will deal with `SandboxReactNativeView` component in your JSX:
52+
53+
```jsx
54+
<SandboxReactNativeView
55+
style={styles.sandboxContainer}
56+
jsBundleSource={'my-plugin'}
57+
moduleName={'PluginComponent'}
58+
onMessage={(message) => {
59+
console.log(`Message: ${message} received through safe API`)
60+
}}
61+
onError={(error) => {
62+
console.warn(`Sandbox error: ${error.message} - handle gracefully without crashing host`)
63+
return false // Error handled
64+
}}
65+
/>
66+
```
67+
68+
The `jsBundleSource` property is flexible and supports multiple ways to load your sandbox code:
69+
- **Bundle name**: `'my-plugin'` - references a named bundle
70+
- **Local files**: bundled into the app during build time
71+
- **Remote URL**: `'https://example.com/plugin.bundle.js'` - dynamically loaded bundles
72+
73+
You can also control security and permissions using `allowedTurboModules` to specify which native modules the sandbox can access i.e. whitelist approach
74+
75+
## It's show time!
76+
77+
Our demo app is delightfully destructive—in the name of science, of course.
78+
79+
![Demo Screenshot](../apps/demo/docs/screenshot.png)
80+
81+
On the left, you'll see the "Main App" column running a component directly in the host application. On the right, the "Sandboxed" column runs the exact same component inside a `SandboxReactNativeView`. While they visually look identical, the sandboxed version is running in complete isolation.
82+
83+
```jsx
84+
<View>
85+
<View>
86+
<Text>Main App</Text>
87+
<CrashIfYouCanDemo />
88+
</View>
89+
<View>
90+
<Text>Sandboxed</Text>
91+
<SandboxReactNativeView
92+
style={styles.sandboxView}
93+
jsBundleSource={'sandbox'}
94+
moduleName={'CrashIfYouCanDemo'}
95+
onError={error => {
96+
Toast.show({...})
97+
return false
98+
}}
99+
/>
100+
</View>
101+
</View>
102+
```
103+
104+
`CrashIfYouCanDemo` component provides collection of buttons that would make any QA engineer reach for their coffee:
105+
106+
- **Crash App**: Calls undefined global methods that would normally bring down the entire application
107+
- **Overwrite Global**: Hijacks `console.log` and other global variables, potentially breaking logging throughout the app
108+
- **Access Blocked TurboModule**: Attempts to use native modules that have been restricted for the sandbox
109+
- **Infinite Loop**: Because sometimes you just want to watch the world burn (or at least the JavaScript thread)
110+
111+
The magic happens when you start pressing buttons. Actions triggered in the main app can crash, freeze, or destabilize your entire application—exactly what you'd expect. But when you trigger the same destructive actions in the sandboxed environment? The sandbox contains the chaos, logs the errors gracefully, and your main app keeps running like nothing happened.
112+
113+
## FAQ (First-time Asked Questions)
114+
115+
**Q: Is this safe for production?**
116+
A: Yes, with proper configuration and testing. Each instance is isolated, and you control which native modules are exposed (more information in [Security Considerations](https://github.com/callstackincubator/react-native-sandbox?tab=readme-ov-file#-security-considerations) section of README)
117+
118+
**Q: What about performance?**
119+
A: Each sandboxed instance has its own JS runtime, so there is some overhead. For most plugin/multi-tenant use cases, the tradeoff is worth it for the isolation and flexibility.
120+
121+
**Q: Can sandboxes communicate with each other?**
122+
A: Not directly. All communication goes through the host app via a safe, message-passing API. But we consider it as possible feature for future
123+
124+
**Q: What platforms are supported?**
125+
A: iOS at the moment
126+
127+
**Q: Can I restrict what a plugin can do?**
128+
A: Yes. You can whitelist which native modules (TurboModules) are available to each sandbox, limiting access to sensitive APIs.
129+
130+
## What is the next
131+
132+
We have a lot of ideas of upcoming features in our [Roadmap](https://github.com/callstackincubator/react-native-sandbox?tab=readme-ov-file#-roadmap) is something is missing don't hesitate to [let us know](https://github.com/callstackincubator/react-native-sandbox/issues/new)
133+
134+
[![Let's see how deep recursive example goes](./images/how-deep.png)](https://github.com/callstackincubator/react-native-sandbox/blob/main/apps/recursive/README.md)
135+

docs/images/hold-my-beer.png

423 KB
Loading

docs/images/how-deep.png

362 KB
Loading

docs/images/yo-dawg.png

191 KB
Loading

0 commit comments

Comments
 (0)