0002 - Use React + Capacitor Over React Native
Status: Accepted Date: 2026-03-21 Author: Manuel Nucci
Context
Feel Pro Club (FPC) must run on three platforms: iOS, Android, and the web. The web experience is not optional — it serves as the entry point for the invitation flow. When a user receives an invitation link, they land on a web page that shows what they're joining (community details, who invited them, what to expect) before being prompted to download the native app. This requires a fast-loading, lightweight, genuine web experience.
Two main approaches were evaluated:
- React Native + react-native-web — Write a single React Native codebase and export it to the web using
react-native-web. - React (web-first) + Capacitor — Build a standard React web application and wrap it for native iOS/Android using Capacitor.
Key findings from evaluating React Native for web:
- Many React Native components don't map cleanly to web equivalents, leading to layout inconsistencies and workarounds.
- Third-party React Native library support for web is inconsistent — many popular libraries don't support the web target at all.
- Styling via
StyleSheetdiverges from standard CSS, making it harder to achieve a polished, web-native feel. - The resulting web bundle is significantly heavier than a standard React application.
- The web output feels like a mobile app running in a browser rather than a proper web experience.
Decision
We will use React + Capacitor to build FPC as a web-first application that also runs natively on iOS and Android.
- The application is built as a standard React app using the web ecosystem (React 19, Vite, Tailwind CSS, shadcn/ui, React Router).
- Capacitor wraps the web app into native iOS and Android shells, providing access to native device APIs (camera, push notifications, haptics, filesystem) through its plugin system.
- The web app is deployed independently and serves as the primary experience for invitation links, onboarding previews, and desktop access.
Consequences
Positive
- First-class web experience — Standard HTML/CSS/JS means fast page loads, proper SEO, and a natural web feel for the invitation flow.
- Single codebase — One React codebase serves web, iOS, and Android without platform-specific forks.
- Full web ecosystem access — Any React/web library works out of the box (shadcn/ui, TanStack Query, Zustand, React Hook Form, i18next, etc.) with no compatibility concerns.
- Lower hiring bar — Standard React and web development skills transfer directly; no need for React Native expertise.
- Progressive enhancement — Native capabilities are added incrementally via Capacitor plugins rather than being a requirement from day one.
Negative
- Native performance ceiling — Complex animations, gesture-heavy interactions, and native list virtualization are harder to achieve compared to React Native's direct native rendering.
- Non-native UI feel — The app won't automatically adopt platform-specific UI conventions (iOS navigation patterns, Android Material Design) without explicit effort.
- Smaller plugin ecosystem — Capacitor's plugin ecosystem is smaller than React Native's, which may require writing custom plugins for less common native APIs.
Mitigations
- FPC is a community and content management app, not a game or media-heavy application — performance-intensive native rendering is not a core requirement.
- CSS animations, web APIs, and Capacitor's built-in plugins (camera, push notifications, geolocation, haptics) cover the vast majority of FPC's native needs.
- Custom Capacitor plugins can be written for edge cases that the existing ecosystem doesn't cover.
- Platform-specific styling can be applied via CSS media queries and Capacitor's platform detection API where needed.