ADR-007: Frontend framework — React/Next.js with Capacitor¶
| Status | Superseded |
| Date | 2026-04-10 |
| Deciders | CTO, Head of Architecture |
| Affects repos | bank-app |
| Superseded by | ADR-057 |
⚠️ This ADR has been superseded by ADR-057.
Status¶
Accepted — 2026-04-10
Context¶
ADR-004 established a single frontend codebase serving both customer and back office surfaces. ADR-026 confirmed the customer surface is mobile-only (iOS and Android app store distribution). This ADR decides the framework and resolves how a single codebase produces both a native mobile app and a back office web application.
Requirements: - Customer surface: iOS and Android app store distribution — not a PWA - Back office surface: data-dense desktop web interface for staff - Single codebase, single component library (ADR-004) - Native device API access: biometric auth (ADR-026), camera for KYC document upload - Strong TypeScript support, large hiring market, AI tooling quality
Decision¶
React / Next.js is the frontend framework. Capacitor wraps the compiled React output
for native app store distribution. The bank-app repo produces two build targets:
| Build target | Output | Distribution | Users |
|---|---|---|---|
build:web |
Static web app | CDN (back office only) | Staff — desktop browser |
build:mobile |
Capacitor native shell | iOS App Store + Google Play | Customers — mobile only |
Both targets share the same React component library, design system, and business logic. The mode switch (customer vs back office) follows the JWT role claim pattern established in ADR-004. Mobile-specific components (biometric prompts, camera access, push notifications) use Capacitor plugins — they are no-ops in the web build.
Back office is web-only. There is no expectation of a back office mobile experience.
Why React over Vue¶
Vue/Nuxt is a credible alternative. The deciding factors are: larger hiring market in AU/NZ for a financial services startup, significantly better AI code generation quality (relevant given DT-011), and React's dominance in the fintech component ecosystem (Radix, shadcn/ui, Recharts, Tremor). The engineering quality difference is small; the ecosystem and hiring difference is meaningful.
Why Capacitor over React Native¶
React Native Web's desktop experience is poor — complex back office dashboards are constrained by the styling system. Capacitor wraps the full React/Next.js web output, so the back office web app and the customer mobile app share 100% of the application layer. Native device APIs (Face ID, camera, push notifications) are accessed via Capacitor plugins without changing the React component code.
Options evaluated¶
| Option | Customer mobile | Back office desktop | Single codebase | Decision |
|---|---|---|---|---|
| React/Next.js + Capacitor | ✓ App Store via Capacitor | ✓ Full React component ecosystem | ✓ | Selected |
| Vue/Nuxt + Capacitor | ✓ | ✓ | ✓ | Credible; ecosystem and hiring edge to React |
| Ionic + Capacitor | ~ Mobile-first; constrained | ✗ Data-dense views awkward | ✓ | Rejected |
| React Native + RN Web | ✓ True native | ✗ Poor desktop UX | ~ | Rejected |
Constraints this creates for bank-app¶
- All components must render correctly in both web and mobile builds
- Capacitor plugin calls must be guarded with platform detection — web build must degrade gracefully
- Bundle discipline required: customer mobile build must satisfy NFR-016 (≤ 500kb gzipped) and NFR-017 (TTI ≤ 2s on 4G)
- No server-side rendering for the mobile build — static export only
Signoff record¶
| Date | Name | Role | Status |
|---|---|---|---|
| 2026-04-10 | Ross Millen | CTO | Approved |
| 2026-04-10 | Ross Millen | Head of Architecture | Approved |
| 2026-04-10 | Ross Millen | Head of Data | Approved |
Capabilities¶
| Capability | Description | Relationship |
|---|---|---|
| CAP-024 | Biometric login (Face ID / fingerprint) | enabled — Capacitor plugins provide native biometric API access |
| CAP-036 | Passkey / FIDO2 authentication | enabled — Capacitor WebAuthn plugin enables passkey registration and challenge |
| CAP-073 | Dual-mode rendering engine (customer + back office) | enabled — Capacitor for mobile customer app; web build for back office |
| CAP-075 | Shared UI component library | enabled — single React component library underpins both build targets |
| CAP-110 | App navigation & deep linking | enabled — Next.js router and Capacitor deep link handling |
| CAP-117 | Document upload & secure storage | enabled — Capacitor camera plugin enables in-app KYC document capture |
Related decisions¶
| ADR | Title | Relationship |
|---|---|---|
| ADR-004 | Single frontend codebase for customer and back office | this ADR implements the framework decision for ADR-004 |
| ADR-026 | Customer authentication — Cognito, mobile-first, passwordless | mobile-only customer surface confirmed; biometric plugins required |
| ADR-034 | Web app hosting and mobile app distribution | deployment targets for both build outputs |
All ADRs
Compiled 2026-05-22 from source/entities/adrs/ADR-007.yaml