Table of Contents
Apr 23, 2025

From Struggle to Simplicity: How We Built a Universal App with Expo & Gluestack UI

Learn how we built a cross-platform Universal App using Expo Router, ES hosting, Gluestack UI & NativeWind—from setup to styling & deployment.
From Struggle to Simplicity: How We Built a Universal App with Expo & Gluestack UI
Prince Kumar Thakur
Prince Kumar ThakurTechnical Content Writer

Editor’s Note: This blog is adapted from a talk delivered by Rajath and Vaibhavi, software engineers at GeekyAnts and core contributors to gluestack UI, during the React Native Meetup. What follows is a personal walkthrough of their journey building Universal Apps—with real struggles, breakthroughs, and the tools that made it all easier.

Have you ever wanted to build an app once and have it work everywhere—Android, iOS, and the web—without writing three different codebases?

We have. And we have struggled.

I’m Rajath, and along with Vaibhavi, we are part of the team building gluestack UI and theappmarket at GeekyAnts. In our journey toward building what we now call a Universal App, we faced the usual challenges: platform quirks, styling inconsistencies, and the sheer overhead of maintaining different versions of the same app.

So we decided to rethink the whole thing. The goal? One codebase. One deployment flow. And one seamless user experience across every screen size and platform.

What Is a Universal App?

Universal App is not a marketing buzzword. It means writing code once—a single source of truth—that runs on Android, iOS, and the web. And not only the UI—we’re talking server endpoints, API routes, and real functionality that doesn’t break when you change platforms.

The key to making this real? Expo Router with ES hosting.

Simplifying Hosting with Expo Router + ES

One of the most impactful updates in the Expo ecosystem has been the introduction of ES hosting with full web support. This advancement allows us to deploy truly full-stack applications—complete with web rendering, API routes, and server-side logic—through a unified, streamlined workflow.
Here’s what the setup looked like for us:

  • First, we updated our app.json to switch the web output from static to server.
  • Then, we dropped our API routes directly inside the app directory (/app/api) using the new format (+api.ts).
  • With a few CLI commands like npx expo export --platform web and npx es deploy, we had our Universal App live.
  • We even got access to crash logs, analytics, request tracking, and deployment history via the ES Dashboard—no extra setup required.

Honestly, it felt like cheating. For the first time, deploying a full-stack Universal App didn’t feel like an uphill climb.

Styling That Feels Like Tailwind, Even in React Native

As someone who came from a web background, styling in React Native always felt... off. StyleSheet.create, TextInput, Pressable—it felt like learning a new dialect of CSS.

That changed for us when we discovered NativeWind.

NativeWind lets you use Tailwind-style utility classes directly inside React Native components. Want a white background and centered layout? Just write className="bg-white justify-center items-center"—and it works across web and native. Even better, all the heavy lifting happens at build time, so you don’t take a runtime hit.

If you’re a fan of Tailwind on the web, this will feel like home.

UI That’s Built Once and Works Everywhere

Let’s talk about UI. Because even if you get your logic and hosting right, building a good-looking, accessible, and responsive UI across platforms is still a beast.

That’s where Gluestack UI came in.

We built Gluestack UI as an open-source component library that’s both universal and fully customizable. During our demo, we showed how we used npx gluestack-ui init to set things up and added a pre-built Alert component in minutes.

What surprised even us was how easy it was to tweak and extend components:

  • We changed the success color on the Alert.
  • We created a new “primary” variant with purple accents.
  • We modified icons and layout styling right inside our theme files.

And all of it worked—on web, iOS, and Android—without additional effort. That’s the kind of consistency we’ve always wanted as developers.

Final Thoughts: From Friction to Flow

Building Universal Apps used to feel like stitching together three broken workflows. Today, it feels like a creative process again.

With Expo Router, ES hosting, NativeWind, and Gluestack UI, we have reached a point where we can focus on what matters—building products—not fighting the tooling.

So, if you have ever hesitated to dive into cross-platform development because it looked too complex, we hope our journey shows you it’s not only possible—it’s kind of fun.

Give it a try. Build something universal. And if you get stuck, reach out—we’d love to help.

See you at the next Meetup!

Book a Discovery Call.

SHARE ON

Articles

Dive deep into our research and insights. In our articles and blogs, we explore topics on design, how it relates to development, and impact of various trends to businesses.