Skip to content

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

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