Callstack's React Native super app, three mini apps loaded at runtime
Example of using micro-frontends in a React Native mobile app with Re.Pack to create a Super App.
At a glance
- What is it?
- This Callstack example builds a fintech super app from three independently deployed React Native mini apps, Trading, Wallet and Auth, loaded at runtime by a host shell with Re.Pack and Module Federation. It suits teams evaluating micro-frontends on mobile, and its value is as a reference architecture rather than a template, since the native dependency ownership rules are the actual lesson.
- Who is it for?
- Adopt the patterns in this repository if you are running several React Native teams that need independent release cycles, because the reference architecture shows how to keep native dependencies in one place and share a single live data connection across mini apps. Do not adopt it as a starting application, since it comes with its own product surface, its own Kraken websocket integration and a fixed set of pinned versions.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The release-cadence problem a monorepo does not solve
The project states the problem in the opening section, and it is worth repeating because it frames everything else.
As fintech products grow, they need to offer multiple services, trading, portfolio management, account settings, while maintaining independent release cycles and team ownership. A classic monorepo helps draw boundaries but still ships everything together: one team's change can block another's deployment, and every user downloads the entire app regardless of which services they actually use.
That second point is the one that separates this from ordinary modularisation. The complaint is not only about deployment coupling, it is about download size, since a user who only wants a portfolio view still installs the trading code.
The framing also names the precedent. Web teams have had micro-frontend architecture for years, and the README says mobile has not had an equivalent until now. So the example is not arguing that micro-frontends are new, it is arguing that the tooling has now caught up on mobile, which is what Re.Pack and Module Federation version 2 provide here.
Three mini apps loaded at runtime by a native host shell
The architecture is described as a production-grade micro-frontend architecture for React Native using Re.Pack and Module Federation. Each mini app, Trading, Wallet and Auth, is an independent JavaScript bundle loaded at runtime by the host shell, so teams can develop, test and deploy a mini app independently, and users download only the bundles they need.
Three properties are named as the payoff. Runtime dependencies mean updating a mini app takes effect immediately without a host app release. Independent deployability means each mini app has its own dev server, bundle and release pipeline. Shared singletons mean native libraries such as react-native and react-native-reanimated, along with the live price feed KrakenWebSocketService, are shared across all mini apps at runtime, keeping bundle sizes small and behaviour consistent.
The application itself is a dark-themed fintech super app with three tabs. Trading lives in packages/trading and shows a live crypto asset list, a Skia price chart and a trade bottom sheet. Wallet lives in packages/wallet with a real-time portfolio balance and per-asset holdings. Account lives in packages/auth with a demo user profile and sign-out. Authentication is handled by a shared AuthProvider federated from packages/auth, and it gates the tab bar until the user signs in.
One detail to notice: the live price feed is shared rather than duplicated, so the Trading and Wallet screens look at the same WebSocket connection rather than opening one each.
All native dependencies live in the host, everything else is a peer
This is the design decision worth copying, and it is stated as the first of the key design decisions: all native dependencies live in host. Mini apps declare them as peerDependencies and consume them as Module Federation shared singletons, which the README says avoids duplicate native modules and double-initialisation crashes.
That last phrase is the whole argument. In a React Native app, a native module that exists in two bundles is not a duplication of code, it is two instances of a stateful object with a lifecycle, and the second one to initialise can break the first. Keeping the native side in one bundle and sharing the JavaScript side as a singleton is what makes the split safe.
The second decision is that the sdk package is a shared singleton. Its PriceContext and KrakenWebSocketService instance are the same object across the host and all mini apps, which provides a single WebSocket connection shared by Trading and Wallet. The third is a build-level detail that makes the peer dependency scheme work in practice: each mini app's rspack.config.ts points resolve.modules at ../host/node_modules, so the bundler can locate peer dependencies during compilation without duplicating them.
The fourth decision is about scheduling rather than structure. useTransition wraps all price state updates, marking them as non-priority so live ticks never block user interactions. A websocket that fires every few hundred milliseconds will otherwise make a list feel unresponsive, and this is the kind of detail that separates a demonstration from an architecture you would put in front of users.
Running it: pnpm, four dev servers and four ports
The requirements are Node.js 24.18 or newer and pnpm 11.20.0, and the pnpm version is installed globally:
npm install -g [email protected]On macOS, Homebrew Ruby is required for the pod install step:
export PATH="/opt/homebrew/opt/ruby/bin:$PATH"Dependencies for all packages are installed with pnpm install, and the pods script covers the iOS side only. The dev servers are started through mprocs:
pnpm start
pnpm run:host:ios
pnpm run:host:androidThe start script runs mprocs with the mprocs/host.yaml configuration, which is how a single command brings up the host and every mini app together. The package.json also carries a pods:update script, an align-deps script that runs across the workspace, and a check-deps script that installs with a frozen lockfile and then runs pnpm peers check, which is the tool that verifies peer dependency declarations are actually satisfied.
Each app has its own port: host on 8081, trading on 9001, wallet on 9002 and auth on 9003. Those fixed ports are not incidental, because Module Federation remotes are addressed by URL, so every mini app dev server has to be reachable at a known address for the host to fetch the bundle at runtime.
The quality gate is four commands across every package
The repository documents its own quality tooling in a single block:
pnpm test # run all tests
pnpm lint # ESLint across all packages
pnpm typecheck # TypeScript across all packages
pnpm format:check # Prettier formatting across the repositoryEach of those scripts is a workspace-wide fan-out. The test script runs pnpm -r test, the lint script runs pnpm -r lint, and typecheck does the same, while format:check runs prettier over the whole repository rather than per package, with prettier configured through a .prettierrc and a @prettier/plugin-oxc dev dependency. The format script is the write variant, prettier . --write.
The React Compiler is in the mix, with babel-plugin-react-compiler 1.x listed in the stack and a dependency on the package in the root manifest. The engineStrict flag is set in the root package.json alongside the Node engine requirement, so a mismatched Node version fails the install rather than failing later in a confusing way.
The other repository files describe a project with process rather than just code: a CLAUDE.md, a CODE_OF_CONDUCT.md, a CONTRIBUTING.md, a PRIVACY_POLICY.md, a RELEASING.md, a patches/ directory, an mprocs/ directory, and a .node-version alongside a .ruby-version. The patches directory is the interesting one, since pnpm patches are how you carry a local modification to a dependency, which is often necessary when a mini app and the host need different behaviour from a shared library.
The stack is pinned, and the release tags are from 2023
The stack table is specific enough to be useful. React Native 0.87.1, React 19.2.8, Re.Pack 5.4.2 which is Rspack-based, and Module Federation version 2 at 2.9.1. Animation is react-native-reanimated 4.7.0 with react-native-worklets 0.13.0. Charts use victory-native 42.0.1, described as Skia-based, and lists use @legendapp/list 3.4.0, with @gorhom/bottom-sheet 5.2.14 for the bottom sheet and @react-navigation/native 7.4.1 with react-native-bottom-tabs 1.4.0 for navigation.
A note on that table. The versions describe what the example currently pins, and because a super app hands a host binary to users, changing a native dependency version is not a routine upgrade in the way it is for a normal app. That is the practical argument for the architecture: the native side moves on a slower clock than the JavaScript side, and the Module Federation split lets the fast side move without forcing the slow side to ship.
The release history tells the other half of the story. The listed releases are the individual mini app packages, shopping-ios, shopping-android and dashboard-ios, all at 0.0.1 and all dated 2023-06-15. The last push to main was recent, so the example itself is being kept current while the published package tags remain at the initial version. The repository is a reference implementation that evolves in place, not a versioned product, and the licence is MIT with a LICENSE file at the root.
If you are evaluating this, the fastest way in is the running demo and the architecture description, not the package tags.
Editorial conclusion
Adopt the patterns in this repository if you are running several React Native teams that need independent release cycles, because the reference architecture shows how to keep native dependencies in one place and share a single live data connection across mini apps. Do not adopt it as a starting application, since it comes with its own product surface, its own Kraken websocket integration and a fixed set of pinned versions. Before you copy anything, read the shared singleton rules, since all native dependencies live in the host and mini apps consume them as peer dependencies, check that your bundler strategy works with the Re.Pack version you plan to use, and note the release history, where the mini app packages are still at 0.0.1 with tags from 2023 while the repository itself is still being pushed to.
Frequently asked questions
What is the callstack React Native super app example?
It demonstrates micro-frontends in a React Native mobile app, using Re.Pack and Module Federation to build a fintech super app. Each mini app, Trading, Wallet and Auth, is an independent JavaScript bundle loaded at runtime by the host shell, and the licence is MIT.
How does the super app example share native dependencies between mini apps?
All native dependencies live in the host package, and mini apps declare them as peerDependencies and consume them as Module Federation shared singletons, which the README says avoids duplicate native modules and double-initialisation crashes. Each mini app's rspack.config.ts points resolve.modules at ../host/node_modules so the bundler can find them at compile time.
How do I install the dependencies and run the React Native super app demo?
You need Node.js 24.18 or newer and pnpm 11.20.0, installed with npm install -g [email protected]. Then run pnpm install and pnpm pods for iOS, pnpm start to bring up all dev servers through mprocs, and pnpm run:host:ios or pnpm run:host:android to run the host app.
Which ports do the host and mini apps use in the super app example?
The host runs on port 8081, trading on 9001, wallet on 9002 and auth on 9003. The fixed ports matter because Module Federation resolves remotes by URL, so each mini app dev server has to be reachable at a known address.
What is shared between the Trading and Wallet mini apps?
The sdk package is a shared singleton, so its PriceContext and KrakenWebSocketService instance are the same object across the host and all mini apps, giving a single WebSocket connection shared by Trading and Wallet. Price state updates are wrapped in useTransition so live ticks are marked non-priority and do not block user interaction.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/callstack-super-app-showcase)Was this useful?