Expo Nov 19, 2025

Going Universal: From a brownfield React Native and Next.js stack to one Expo app

M10 Related OWASP risk: Insufficient Cryptography Learn more →

Article Summary

Gunnar Torfi shares how a single developer maintained 40+ mobile screens AND a full web app by merging them into one universal codebase. No big rewrite required.

The Noona team was drowning in duplicate work: separate React Native and Next.js codebases meant building every feature twice. With just one developer maintaining the product, they gradually migrated to a single Expo app that runs on iOS, Android, and web without sacrificing velocity.

Key Takeaways

Critical Insight

A small team unified their brownfield React Native and Next.js stack into one Expo app over several months while continuously shipping product, eliminating duplicate work and achieving feature parity across platforms.

Their approach to handling platform-specific components (payment flows, deep links, native pickers) while keeping 95% of code shared reveals a practical blueprint for any team considering this path.

About This Article

Problem

Noona maintained separate codebases for Expo and Next.js, which meant every bug fix and feature had to be built twice. This created duplicate work and made code reviews exhausting.

Solution

The team set up a Turborepo monorepo with shared UI packages using React Native primitives and react-native-web. They used platform-specific file extensions like .native.ts and .web.ts to handle components such as Image, Link, and payment handlers.

Impact

Features are now organized in packages/ui/features/*, so Noona ships to web and mobile at the same time without needing to coordinate releases. New features get written once and work on both platforms immediately.