Universal Apps
A Universal App is a React Native application that targets mobile (iOS and Android) and the web from the same codebase. The term is meant to separate this idea from the older “cross-platform” label, which historically just meant “it works on both iOS and Android.” Universal shifts the scope: one repo, three major platforms.
The concept started to gain traction once React Native for Web matured enough to make the DOM a first-class target. Suddenly, the “write once, run
anywhere” mantra had a plausible web leg. Meta themselves list Web as a supported platform for React Native (Wikipedia), signalling it’s not an afterthought.
The idea of a Universal React Native app didn’t spring out of thin air. React Native Web was first released in 2016 by Nicolas Gallagher, mapping React Native primitives onto DOM elements. It quickly proved itself in production with apps like Twitter Lite and Flipkart, but it was mostly treated as an oddity — something you could do, but wouldn’t bet the company on.
By 2018–2019, some pioneers started proving otherwise. Nozbe was one of the earliest to openly commit to a single codebase across iOS, Android, and the web. Around the same time, Krzysztof Magiera introduced ZACS (Zero-Abstraction-Cost Styling) at React Native EU 2019, an early stab at compiling style props away for performance. That philosophy would later resurface in tools like Tamagui.
If React Native Web made universal apps possible, Expo made them practical. What started as a convenience wrapper around React Native evolved into the platform that quietly underpins most universal work today.
Expo integrated React Native Web into its managed workflow as early as SDK 33 (2019), making it trivial to spin up projects that targeted mobile and web. That lowered the barrier so dramatically that experimentation turned into habit.
They went further. Most of Expo’s own modules — from camera to notifications to file system — are written with web support in mind, and occasionally even desktop. That means developers aren’t blocked the moment they try to ship a web build; the ecosystem itself is universal-aware.
By the mid-2020s, the idea of “Universal React Native” had hardened into strategy rather than experiment. Teams like Kooth / Soluna (2025) built their web app directly from their React Native codebase. They avoided a split React/Next.js fork and shipped faster, even if navigation and accessibility on web still showed rough edges. In parallel, essays like raf.dev’s take on Universal RN framed it as operational efficiency: one design system, one engineering team, fewer silos.
Developers themselves back this up. In practice, building universal isn’t a neat 1× cost saving — more like 1.5× the work instead of 2×. There are always platform-specific branches, but the shared foundation pays off.
On the infrastructure side, Expo Application Services (EAS) filled in the missing operational puzzle pieces. EAS Build (previewed in October 2020, GA by late 2021) made cloud builds routine. EAS Submit handled app store delivery. EAS Update kept over-the-air updates flowing. And in January 2025, Expo unveiled EAS Hosting — a platform for deploying web builds, server functions, and APIs alongside your mobile app. In other words, the first universal-native CI/CD pipeline.
The other milestone was the release of Expo Router (2022, stabilised through 2023–24). Inspired by Next.js, it brought file-based routing to React Native — and critically, it worked just as well on the web as on mobile. For the first time, navigation in a Universal App didn’t feel like a compromise. Developers could share routes, nested layouts, and deep links across platforms with almost no platform-specific code. In practice, Expo Router gave React Native Web something it had always lacked: navigation that felt natural in a browser.
Even desktop hasn’t been ignored. The Expo team has openly eyed the platform, writing modules that can stretch in that direction. It’s not mainstream yet, but the intent is clear: wherever React Native runs, Expo wants to be the glue.
Universal development quickly ran into styling headaches. React Native for Web solved the primitive problem (<View> → <div>, <Text> → <span>), but it never solved design systems. On mobile you can get away with inline styles or StyleSheet.create; on web, you’re expected to have responsive layouts, theming, media queries, accessibility hooks… things React Native never had to think about.
Early attempts leaned on Tailwind-for-RN solutions like NativeWind. It worked, technically, but felt awkward on web — className soup, no type-safety, and too many cases where web expected CSS features that weren’t there. Out of that frustration, two stronger contenders emerged:
By 2024, the split was clear: Tamagui for teams that want batteries-included (and don’t mind its opinions), Unistyles for those who just want a lean styling engine. Developers on Reddit tend to describe Tamagui as the less painful option when you actually need universal components to behave consistently across mobile and web.
It’s worth noting that both tools exist because React Native’s core styling model was never designed for the web. Flexbox everywhere is fine until you hit responsive breakpoints, or need to switch themes dynamically, or want a component library that looks native on both DOM and UIKit. Universal apps made those cracks impossible to ignore — and Tamagui/Unistyles are basically attempts to plaster over them with different philosophies.