Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
489e548
chore: add refresh plan and requirements, update lockfiles
burczu Apr 27, 2026
270d04a
chore: add CLAUDE.md with codebase guidance
burczu Apr 27, 2026
c4c2538
feat: US-1 repo cleanup — remove booking, shopping, dashboard mini apps
burczu Apr 27, 2026
8575b2b
feat: US-2 shared WebSocket price feed in sdk package
burczu Apr 27, 2026
73bccd5
feat: US-3 host app shell with dark theme, tabs, and native deps
burczu Apr 27, 2026
0cfede8
feat: US-4 dark Fintech sign-in screen
burczu Apr 27, 2026
8eb5bbe
feat: US-5 trading mini app with live asset list and price animations
burczu Apr 27, 2026
e4edd06
feat: US-6 asset details screen with live chart and news
burczu Apr 28, 2026
4c8ee62
feat: US-7 trade bottom sheet and success screen
burczu Apr 28, 2026
9dda993
feat: US-8 wallet mini app with real-time portfolio balance
burczu Apr 28, 2026
0483893
fix: wire up trading and wallet dev servers and shared module graph
burczu Apr 28, 2026
ce75ddb
fix: add react-native-worklets/plugin to babel configs
burczu Apr 28, 2026
55782ea
feat: US-9 polish — React Compiler, connection status, README
burczu Apr 28, 2026
25e4ada
fix: add SF Symbol icons to bottom tab bar
burczu Apr 28, 2026
0578e03
fix: use useBottomTabBarHeight for trade button footer padding
burczu Apr 28, 2026
8c4c840
fix: use useSharedValue for price direction in flash animation
burczu Apr 28, 2026
f145f5d
fix: resolve TypeScript module resolution errors in WebStorm
burczu Apr 28, 2026
08a5232
fix: eliminate dual pnpm react-native instances causing RCTText crash
burczu Apr 29, 2026
b34331b
feat: extend SDK with shared utilities, components, and type exports
burczu Apr 29, 2026
7a723a8
refactor: migrate mini apps to use shared SDK utilities
burczu Apr 29, 2026
0e81b67
fix: improve auth type safety and action dispatch semantics
burczu Apr 29, 2026
88cc15b
fix: remove independent prop from NavigationContainer in standalone s…
burczu Apr 29, 2026
12df44e
feat: prepopulate asset details chart with Kraken OHLC history
burczu Apr 29, 2026
770a7f4
feat: add y-axis price labels to asset details chart
burczu May 5, 2026
415634c
refactor: consolidate theme, icon util, and fix ConnectionBanner dete…
burczu May 5, 2026
d22f16f
feat: add Account tab to bottom navigation with polished screen
burczu May 5, 2026
fb5035c
docs: rewrite README with problem/solution structure
burczu May 6, 2026
4d1251e
feat: add demo load delay and consistent dark loading states
burczu May 6, 2026
749cbcb
fix: start auth in loading state to prevent unauthenticated shell flash
burczu May 6, 2026
37e7ba9
fix: clean up jest setup — remove stale mocks, add gesture handler an…
burczu May 6, 2026
26cfc56
fix: add MF module declarations and SDK types field for TypeScript
burczu May 6, 2026
a5c8dba
chore: remove stale dashboard/booking/shopping scripts and mprocs ent…
burczu May 6, 2026
dc9cfd7
refactor: consolidate useFlashAnimation into SDK, remove local copies
burczu May 6, 2026
b283fc7
perf: wrap chart data update in startTransition to defer render on pr…
burczu May 6, 2026
e7e6721
perf: extract PriceCell and ValueCell to isolate price subscription r…
burczu May 6, 2026
6bbea95
docs: add Module Federation demo guide and business case article
burczu May 6, 2026
2e87eb0
docs: add app screenshots and trading GIF, remove stale images
burczu May 6, 2026
228fd03
docs: replace ASCII architecture diagram with diagram.png
burczu May 6, 2026
d53af11
docs: add Demo guide section linking to MODULE_FEDERATION_DEMO_GUIDE.md
burczu May 6, 2026
cb79085
docs: replace ASCII diagram with diagram.png in demo guide
burczu May 6, 2026
8e25b01
chore: remove REFRESH_PLAN and REFRESH_REQUIREMENTS — work complete
burczu May 6, 2026
c9c4a44
chore: update CLAUDE.md to reflect current architecture and patterns
burczu May 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"enabledPlugins": {
"react-native-best-practices@callstack-agent-skills": true
}
}
133 changes: 133 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Package Manager

This project uses **pnpm@9.15.3**. Node.js 22+ is required. Ensure both are on PATH before running any commands:

```bash
export PATH="/opt/homebrew/opt/ruby/bin:$PATH" # required for pod commands on macOS
```

## Common Commands

```bash
# Install all workspace dependencies
pnpm install

# Start all dev servers (host + all mini apps) via mprocs
pnpm start

# Run on iOS / Android
pnpm run:host:ios
pnpm run:host:android

# Install iOS CocoaPods (run after adding native dependencies)
pnpm pods

# Run across all packages
pnpm lint
pnpm test
pnpm typecheck

# Run for a single package
pnpm --filter host test
pnpm --filter trading lint
```

## Architecture

This is a **React Native Fintech Super App** using [Re.Pack](https://re-pack.dev) and **Module Federation V2** (Rspack-based) to load mini apps at runtime as separate JS bundles.

### Workspace packages

| Package | Role |
|---|---|
| `packages/host` | Native shell — owns the native binary, all native dependencies, top-level navigation, and MF remote wiring |
| `packages/auth` | Auth mini app — exposes `AuthProvider`, `SignInScreen`, `AccountScreen` |
| `packages/sdk` | Shared library — `KrakenWebSocketService`, `PriceProvider`, hooks, utilities, types, `getSharedDependencies()` for MF |
| `packages/trading` | Trading mini app — live asset list, Skia chart with OHLC history, trade bottom sheet |
| `packages/wallet` | Wallet mini app — real-time portfolio balance using live prices |

### Module Federation pattern

- **Host** loads remotes eagerly (`eager: true`) and is the only app that runs natively.
- **Mini apps** set `eager: false`, expose only `./App` (their `MainNavigator`), and consume `auth` as a remote.
- All shared deps (react, react-native, navigation libs, sdk) are declared as singletons via `getSharedDependencies()` from `sdk`.
- Each mini app's bundler output `uniqueName` must be unique (e.g. `sas-host`, `sas-trading`).
- TypeScript declarations for all federated imports live in `packages/host/src/declarations.d.ts`.

### How host loads a mini app

```tsx
// In host — lazy load a remote module via React.lazy + Suspense
const TradingApp = React.lazy(() =>
randomDelay().then(() => import('trading/App'))
);

<ErrorBoundary name="Trading">
<React.Suspense fallback={<Placeholder label="Trading" />}>
<TradingApp />
</React.Suspense>
</ErrorBoundary>
```

The `randomDelay()` (250–350ms) is intentional for demo purposes — it makes the loading state visible. Remove it for production.

### Native dependencies

**All native deps live in `host`** — mini apps declare them as `peerDependencies` only. When adding a new native dep:
1. Add it to `host/package.json` dependencies
2. Add it to `sdk/lib/dependencies.json` if it should be a MF shared singleton
3. Add it as `peerDependency` in each mini app that uses it
4. Add a `paths` entry in the mini app's `tsconfig.json` pointing to `../host/node_modules/<dep>`
5. Run `pnpm pods` to reinstall iOS pods

### SDK exports

`packages/sdk` is a shared singleton federated across all mini apps. It exports:
- `KrakenWebSocketService` — singleton WebSocket to Kraken, shared across Trading and Wallet
- `PriceProvider` / `PriceContext` — React context wrapping the WS service
- `usePrices()` / `useAssetPrice(symbol)` — price subscription hooks (updates wrapped in `useTransition`)
- `useHistoricalPrices(krakenPair)` — fetches OHLC history from Kraken REST API
- `useFlashAnimation(value)` — Reanimated hook for green/red flash on value change
- `useConnectionStatus()` — WebSocket connection status hook
- `ConnectionBanner` — UI component showing reconnecting/disconnected state
- `ASSETS`, `ASSET_MAP`, `colors`, `formatPrice`, `formatValue`, `getAssetIconUri`

### Auth flow

`AuthProvider` (from `auth` remote) uses a render-prop pattern — it calls `children` with `{ isLoading, isSignout }`. Host's `App.tsx` gates the navigation container behind auth state. Initial state is `isLoading: true` to prevent an unauthenticated shell flash before token restore completes.

### Performance patterns

- **Leaf components**: `PriceCell` (trading) and `ValueCell` (wallet) isolate `useAssetPrice` subscriptions so only the price node re-renders on ticks. The outer row (`AssetRow`, `HoldingRow`) owns Reanimated shared values for the flash animation and never re-renders on price ticks.
- **useTransition**: All price state updates in `usePrices` are wrapped in `startTransition` — price ticks are non-priority and won't block user interactions.
- **startTransition on chart**: `setChartData` in `AssetDetailsScreen` is wrapped in `React.startTransition` to defer chart rebuilds.
- **React Compiler**: `babel-plugin-react-compiler` is enabled across all packages for automatic memoization.

### Dev server ports

| App | Port |
|---|---|
| host | 8081 |
| auth | 9003 |
| trading | 9001 |
| wallet | 9002 |

### Mocks for standalone development

Each mini app has a `mocks/` folder with local stubs for federated modules (e.g. `auth/AuthProvider`). These are used when running a mini app standalone without the host.

### Rspack / Re.Pack config

Each package has an `rspack.config.ts`. The loader used is `@callstack/repack/babel-swc-loader`. Asset transforms use `getAssetTransformRules()` — mini apps use `{inline: true}`.

### Testing

Host has a Jest test suite (`pnpm --filter host test`). Key mocks in `packages/host/jest.setup.js`:
- `react-native-gesture-handler/jestSetup`
- `@bottom-tabs/react-navigation` — mocked (native-only, can't run in Jest)
- `react-native-bootsplash` — mocked
- `@callstack/repack/client` — mocked with `auth`, `trading`, `wallet` container stubs
169 changes: 90 additions & 79 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<a href="https://www.callstack.com/open-source?utm_campaign=generic&utm_source=github&utm_medium=referral&utm_content=super-app-showcase" align="center">
<img src="https://github.com/user-attachments/assets/4ee05e68-54ca-42b3-994c-9de988d66333" alt="Super App Showcase" />
<img src="https://github.com/user-attachments/assets/4ee05e68-54ca-42b3-994c-9de988d66333" alt="Fintech Super App" />
</a>
<h3 align="center">Super Apps in React Native with Re.Pack</h3>
<h3 align="center">Fintech Super App — React Native with Re.Pack & Module Federation</h3>
<div align="center">

[![mit licence][license-badge]][license]
Expand All @@ -10,138 +10,149 @@

</div>

Bring micro-frontend architecture to your mobile [React Native](https://reactnative.dev) app with [Re.Pack](https://re-pack.dev) and make it a Super App. [Learn more.](https://www.callstack.com/services/super-app-development?utm_campaign=super_apps&utm_source=github&utm_content=super_app_showcase)

## The problem

As small apps grow, offering multiple services (payments, messaging, social network, gaming, news, etc.), maintaining them becomes challenging. The codebase can become cluttered, and the app size may deter users who only need a few services. Today, teams dealing with such a challenge can either use monorepo to help draw the boundaries between functionalities, or leverage publishing and consuming packages from npm. However, both approaches have their drawbacks. At the same time, web teams have acccess to micro-frontend architecture, which allows them to split the app into smaller, more manageable parts downloadable on demand.
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.

At the same time, web teams have had micro-frontend architecture for years. Mobile hasn't had an equivalent — until now.

## The solution

This showcase demonstrates how to achieve a proper micro-frontend architecture for mobile apps with [Module Federation](https://module-federation.io). It simplifies setup and maintenance, allowing independent apps to be deployed separately or as part of a super app. Micro-frontends can be moved to separate repositories, enabling independent team work or external contributions. Unlike classic monorepos, this setup uses runtime dependencies, so updating a micro-frontend automatically updates all apps using it without redeployment.
This showcase demonstrates a **production-grade micro-frontend architecture for React Native** using [Re.Pack](https://re-pack.dev) and [Module Federation](https://module-federation.io). Each mini app (Trading, Wallet, Auth) is an independent JavaScript bundle, loaded at runtime by the host shell. Teams can develop, test, and deploy their mini app independently. Users only download the bundles they need.

## The Super App
Key properties of this architecture:
- **Runtime dependencies** — updating a mini app takes effect immediately without a host app release
- **Independent deployability** — each mini app has its own dev server, bundle, and release pipeline
- **Shared singletons** — native libraries (`react-native`, `react-native-reanimated`, etc.) and the live price feed (`KrakenWebSocketService`) are shared across all mini apps at runtime, keeping bundle sizes small and behaviour consistent

## The App

<table>
<tr>
<td>Host App</td>
<td>Mini Apps Interaction</td>
<td>Booking Standalone App</td>
<td>Trading App</td>
<td>Wallet App</td>
<td>Auth App</td>
</tr>
<tr>
<td><img src="images/host-main-screen.png" alt="host-main-screen" width="200"></td>
<td><img src="images/host.gif" alt="host" width="200"></td>
<td><img src="images/booking.gif" alt="booking" width="200"></td>
<td><img src="images/trading-app.gif" alt="trading-app" width="200"></td>
<td><img src="images/wallet-app.png" alt="wallet-app" width="200"></td>
<td><img src="images/auth-app.png" alt="auth-app" width="200"></td>
</tr>
</table>

## Structure
A dark-themed Fintech Super App with three tabs:

<img src="images/super-app-showcase-scheme.png" />
| Tab | Mini App | Description |
|---|---|---|
| Trading | `packages/trading` | Live crypto asset list, Skia price chart, trade bottom sheet |
| Wallet | `packages/wallet` | Real-time portfolio balance, per-asset holdings |
| Account | `packages/auth` | Demo user profile, sign-out |

The super app contains 4 apps:
Authentication is handled by a shared `AuthProvider` federated from `packages/auth`, gating the tab bar until the user signs in.

- `host` - the main app, which is a super app. It contains all the micro-frontends and provides a way to navigate between them.
- `booking` - micro-frontend for booking service.
Booking exposes `UpcomingAppointments` screen and `MainNavigator`. `MainNavigator` is Booking app itself. `UpcomingAppointments` screen is a screen, which is used in the super app in its own navigation.
- `shopping` - micro-frontend for shopping service.
Shopping exposes `MainNavigator`. `MainNavigator` is Shopping app itself.
- `news` - micro-frontend for news service.
News exposes `MainNavigator`. `MainNavigator` is News app itself. News mini app stored in separate repository https://github.com/callstack/news-mini-app-showcase to provide the example of using remote container outside of the monorepo.
- `dashboard` - micro-frontend for dashboard service.
Dashboard exposes `MainNavigator`. `MainNavigator` is Dashboard app itself.
- `auth` - module that is used by other modules to provide authentication and authorization flow and UI.
## Architecture

Each of the mini apps could be deployed and run as a standalone app.
![Architecture diagram](images/diagram.png)

## How to use
**Key design decisions:**

### Requirements
- All native dependencies live in `host`. Mini apps declare them as `peerDependencies` and consume them as Module Federation shared singletons — no duplicate native modules, no double-initialisation crashes.
- `sdk` is a shared singleton: its `PriceContext` and `KrakenWebSocketService` instance are the same object across host and all mini apps, providing a single WebSocket connection shared by Trading and Wallet.
- Each mini app's `rspack.config.ts` points `resolve.modules` at `../host/node_modules` so the bundler can locate peer deps during compilation without duplicating them.
- `useTransition` wraps all price state updates, marking them as non-priority so live ticks never block user interactions.

⚠️ **Important:** This project requires:
## Stack

- Node.js version 22 or higher
- pnpm as package manager
| | |
|---|---|
| React Native | 0.84 |
| React | 19 |
| Re.Pack | 5.2 (Rspack-based) |
| Module Federation | V2 |
| Animations | react-native-reanimated 4 + react-native-worklets |
| Charts | victory-native 41 (Skia-based) |
| Lists | @legendapp/list 2 |
| Bottom sheet | @gorhom/bottom-sheet 5 |
| Navigation | @react-navigation/native 7 + react-native-bottom-tabs |
| React Compiler | babel-plugin-react-compiler 1.0 |

Please refer to the official [pnpm installation guide](https://pnpm.io/installation) for detailed setup instructions.
## Structure

| Package | Role |
|---|---|
| `packages/host` | Native shell — owns binary, all native deps, top-level navigation, MF remote wiring |
| `packages/auth` | Auth mini app — `AuthProvider`, `SignInScreen`, `AccountScreen` |
| `packages/trading` | Trading mini app — live asset list, Skia chart, trade bottom sheet |
| `packages/wallet` | Wallet mini app — real-time portfolio balance and holdings |
| `packages/sdk` | Shared library — `KrakenWebSocketService`, `PriceProvider`, hooks, utils, types |

After installation, it's recommended to align your pnpm version with the project:
## Requirements

- Node.js 22+
- pnpm 9.15.3

```bash
pnpm self-update
npm install -g pnpm@9.15.3
```

### Setup

Install dependencies for all apps:
On macOS, Homebrew Ruby is required for pod install:

```
pnpm install
```bash
export PATH="/opt/homebrew/opt/ruby/bin:$PATH"
```

#### iOS
## Setup

In case automatic pods installation doesn't work when running iOS project, you can install manually:
Install dependencies for all packages:

```
pnpm pods
```bash
pnpm install
pnpm pods # iOS only — install CocoaPods
```

### Running the Super App
## Running

Start DevServer for Host and Mini apps:
Start all dev servers (host + all mini apps) via mprocs:

```
```bash
pnpm start
```

Run Super App on iOS or Android (ios | android):
Run on device/simulator:

```bash
pnpm run:host:ios
pnpm run:host:android
```
pnpm run:host:<platform>
```

### Running the Mini App as a standalone app

> **💡 NOTE**
>
> The "booking" and "shopping" mini-apps can't be run in standalone mode (i.e. without the host running). This is a deliberate decision of this repository to showcase the possibility and to reduce the amount of work to keep the mini-apps dependencies up-to-date.
>
> It's up to you to decide on what kind of developer experience your super app has.

Start DevServer for a Dashboard Mini App as a standalone app:
### Dev server ports

```
pnpm start:dashboard
```
| App | Port |
|---|---|
| host | 8081 |
| trading | 9001 |
| wallet | 9002 |
| auth | 9003 |

### Code Quality Scripts
## Code quality

Run tests for all apps:

```
pnpm test
```

Run linter for all apps:

```
pnpm lint
```bash
pnpm test # run all tests
pnpm lint # ESLint across all packages
pnpm typecheck # TypeScript across all packages
```

Run type check for all apps:
## Demo guide

```
pnpm typecheck
```
Looking to run this in a client demo or build a business case? Read the [Module Federation Demo Guide](docs/MODULE_FEDERATION_DEMO_GUIDE.md) — it covers the architecture, a step-by-step demo script, and a business case template with bundle size and CI time tables.

## Contributing

Read the [contribution guidelines](/CONTRIBUTING.md) before contributing.

## Made with ❤️ at Callstack

Super App showcase is an open source project and will always remain free to use. If you think it's cool, please star it 🌟. [Callstack][callstack-readme-with-love] is a group of React and React Native geeks, contact us at [hello@callstack.com](mailto:hello@callstack.com) if you need any help with these or just want to say hi!
Fintech Super App is an open source project and will always remain free to use. If you think it's cool, please star it 🌟. [Callstack][callstack-readme-with-love] is a group of React and React Native geeks, contact us at [hello@callstack.com](mailto:hello@callstack.com) if you need any help with these or just want to say hi!

<!-- badges -->

Expand All @@ -151,4 +162,4 @@ Super App showcase is an open source project and will always remain free to use.
[prs-welcome-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge
[prs-welcome]: ./CONTRIBUTING.md
[chat-badge]: https://img.shields.io/discord/426714625279524876.svg?style=for-the-badge
[chat]: https://discord.gg/Q4yr2rTWYF
[chat]: https://discord.gg/Q4yr2rTWYF
Loading
Loading