Choosing the right tech stack for Whispcal
Building a mobile app from scratch is a series of irreversible decisions — or at least, decisions that are expensive to reverse. The tech stack is the first and arguably the most consequential.
The constraints
I wanted Whispcal to ship on both iOS and Android from day one. I'm a solo developer with limited time outside of my day job, so I needed something that maximized code reuse without sacrificing native feel.
My non-negotiables:
- TypeScript everywhere (no context switching)
- Hot reload that actually works
- A path to native modules if I ever need them
- Strong community and ecosystem
Why Expo (and not bare React Native)
I spent two weeks with bare React Native before switching to Expo. The DX difference is night and day. With Expo:
npx expo startand I'm running on my phone in seconds- EAS Build handles the CI/CD nightmare of iOS signing
- The file-based router feels like Next.js for mobile
- Over-the-air updates mean I can push fixes without going through app review
The trade-off is less control over native modules, but Expo's ecosystem covers 95% of what I need. For the remaining 5%, there's always the escape hatch of custom dev clients.
State management: Zustand + React Query
I deliberately avoided Redux. For a solo project, Zustand gives me exactly what I need — simple, typed stores with no boilerplate. React Query handles all server state, caching, and background refetching.
The combination is clean: Zustand for UI state (modals, navigation, user preferences), React Query for everything that touches the API.
What I'd do differently
If I started today, I'd probably look more seriously at Expo Router's server components story. It's still early, but the direction is promising. I'd also set up end-to-end tests from day one instead of retrofitting them later.
But overall, I'm happy with the stack. It lets me move fast and stay focused on the product rather than fighting tooling.