Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
43 changes: 43 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Checks

on:
pull_request:
push:
branches:
- main

permissions:
contents: read

jobs:
quality:
name: Format, lint, and typecheck
runs-on: ubuntu-latest

steps:
- name: Check out repository
uses: actions/checkout@v5

- name: Set up pnpm
uses: pnpm/action-setup@v4

- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version-file: .node-version
cache: pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Check formatting
run: pnpm format:check

- name: Lint
run: pnpm lint

- name: Typecheck
run: pnpm typecheck

- name: Test
run: pnpm test
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
24
24.18.0
3 changes: 2 additions & 1 deletion .npmrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
auto-install-peers=false
link-workspace-packages=true
prefer-workspace-packages=true
package-manager-strict-version=true
update-notifier=false
update-notifier=false
10 changes: 10 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
node_modules/
**/node_modules/
**/Pods/
**/vendor/
**/build/
**/dist/
**/.gradle/
**/.cxx/
**/@mf-types/
pnpm-lock.yaml
14 changes: 14 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
arrowParens: avoid
bracketSameLine: true
bracketSpacing: false
singleQuote: true
trailingComma: all
plugins:
- '@prettier/plugin-oxc'
overrides:
- files: '**/*.{js,mjs,cjs,jsx}'
options:
parser: oxc
- files: '**/*.{ts,mts,cts,tsx}'
options:
parser: oxc-ts
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.10
3.2.2
36 changes: 20 additions & 16 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Package Manager

This project uses **pnpm@9.15.3**. Node.js 22+ is required. Ensure both are on PATH before running any commands:
This project uses **pnpm@11.20.0**. Node.js 24.18+ 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
Expand All @@ -30,6 +30,7 @@ pnpm pods
pnpm lint
pnpm test
pnpm typecheck
pnpm format:check

# Run for a single package
pnpm --filter host test
Expand All @@ -42,13 +43,13 @@ This is a **React Native Fintech Super App** using [Re.Pack](https://re-pack.dev

### 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 |
| 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

Expand All @@ -63,21 +64,22 @@ This is a **React Native Fintech Super App** using [Re.Pack](https://re-pack.dev
```tsx
// In host — lazy load a remote module via React.lazy + Suspense
const TradingApp = React.lazy(() =>
randomDelay().then(() => import('trading/App'))
randomDelay().then(() => import('trading/App')),
);

<ErrorBoundary name="Trading">
<React.Suspense fallback={<Placeholder label="Trading" />}>
<TradingApp />
</React.Suspense>
</ErrorBoundary>
</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
Expand All @@ -87,6 +89,7 @@ The `randomDelay()` (250–350ms) is intentional for demo purposes — it makes
### 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`)
Expand All @@ -109,12 +112,12 @@ The `randomDelay()` (250–350ms) is intentional for demo purposes — it makes

### Dev server ports

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

### Mocks for standalone development

Expand All @@ -127,7 +130,8 @@ Each package has an `rspack.config.ts`. The loader used is `@callstack/repack/ba
### 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
- `@callstack/repack/client` — mocked with `auth`, `trading`, `wallet` container stubs
5 changes: 3 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ We follow the [conventional commits specification](https://www.conventionalcommi

### Linting and tests

We type our code with Flow or TypeScript, use ESLint with Prettier for linting and formatting the code, and Jest for testing. Our pre-commit hooks verify that the linter and tests pass when commiting. You can also run the following commands manually:
We type our code with TypeScript, use ESLint for linting, Prettier for formatting, and Jest for testing. Pull requests run all of these checks in CI. You can also run the following commands manually:

- `pnpm typecheck`: run type checks.
- `pnpm lint`: lint files with eslint and prettier.
- `pnpm lint`: lint files with ESLint.
- `pnpm format:check`: check formatting with Prettier.
- `pnpm test`: run unit tests with jest.

### Sending a pull request
Expand Down
64 changes: 33 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ At the same time, web teams have had micro-frontend architecture for years. Mobi
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.

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
Expand All @@ -42,11 +43,11 @@ Key properties of this architecture:

A dark-themed Fintech Super App with three tabs:

| Tab | Mini App | Description |
|---|---|---|
| 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 |
| Wallet | `packages/wallet` | Real-time portfolio balance, per-asset holdings |
| Account | `packages/auth` | Demo user profile, sign-out |

Authentication is handled by a shared `AuthProvider` federated from `packages/auth`, gating the tab bar until the user signs in.

Expand Down Expand Up @@ -78,36 +79,36 @@ flowchart LR

## Stack

| | |
|---|---|
| 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 |
| | |
| ----------------- | ---------------------------------------------------------------- |
| React Native | 0.86.2 |
| React | 19.2.8 |
| Re.Pack | 5.2.5 (Rspack-based) |
| Module Federation | V2 (2.8.1) |
| Animations | react-native-reanimated 4.5.3 + react-native-worklets 0.11.3 |
| Charts | victory-native 41.26.0 (Skia-based) |
| Lists | @legendapp/list 3.3.3 |
| Bottom sheet | @gorhom/bottom-sheet 5.2.14 |
| Navigation | @react-navigation/native 7.3.14 + react-native-bottom-tabs 1.4.0 |
| React Compiler | babel-plugin-react-compiler 1.x |

## 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 |
| 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 |

## Requirements

- Node.js 22+
- pnpm 9.15.3
- Node.js 24.18+
- pnpm 11.20.0

```bash
npm install -g pnpm@9.15.3
npm install -g pnpm@11.20.0
```

On macOS, Homebrew Ruby is required for pod install:
Expand Down Expand Up @@ -142,19 +143,20 @@ pnpm run:host:android

### Dev server ports

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

## Code quality

```bash
pnpm test # run all tests
pnpm lint # ESLint across all packages
pnpm typecheck # TypeScript across all packages
pnpm format:check # Prettier formatting across the repository
```

## Demo guide
Expand Down
Loading
Loading