From altitude sickness to the app store with Expo Router, ElysiaJS, and Nativewind

UsersReact Native4 minutes read

Josep Vidal

Josep Vidal

Guest Author

From mountain failure to mobile triumph — how one developer built 100cims with Expo to track summits, plan hikes, and unite climbers across the world.

From altitude sickness to the app store with Expo Router, ElysiaJS and Nativewind

Last summer I failed.

I set out to conquer my first 5,000m mountain. But at 4,000m, waiting for sunrise, altitude sickness hit me hard. I had to turn back. My group summited, I didn’t.

That failure stuck with me. So I started climbing more. Getting stronger. And as a software developer I decided to over-engineer a solution to track my summits.

That’s how 100cims was born: a personal app that became a passion project.

What Is 100cims?

100cims is a mobile app for mountain lovers. It lets users:

  • Track mountain summits across challenges ( 🇺🇸 US top 150 mountains, 🇪🇸 Catalonia’s 100 cims, 🇫🇷 GR-20 Corsica, 🇪🇺 European Alps…).
  • Earn scores based on mountain difficulty and elevation.
  • See summit history with a visual collage of photos.
  • View a public ranking and compare with friends.
  • Create and join hiking plans with built-in chat 💬.

In under 4 months, 100cims has grown to over 200+ users with 1,000+ summits logged — all 100% organic.

Expo at the core

The app is built entirely in React Native, powered by Expo.

On the app:

  • expo-router powers navigation — bringing file-based routing to React Native with nested layouts, dynamic routes, and modals that just work.
  • nativewind lets me use Tailwind-style utilities directly in React Native. It makes styling fast, scalable, and developer-friendly.
  • A suite of Expo SDKs powers native interactions: expo-store-review, expo-image-picker, expo-haptics, expo-clipboard, expo-device, and more.

The experience across platforms (iOS and Android) is seamless — and thanks to expo-dev-client, development is smooth and blazing fast.

API architecture with ElysiaJS + Eden

Under the hood, the backend runs a typed, minimal setup using Elysia.js, a modern Bun framework that feels like Fastify meets tRPC. It’s built around composability, types, and performance.

  • API routes are organized into public and protected groups
  • Auth is handled with a JWT + Bearer strategy, using @elysiajs/jwt and @elysiajs/bearer
  • Database access is powered by Drizzle ORM, giving me schema-safe queries with type inference on a PostgreSQL DB hosted on Supabase.
  • All API routes are mounted via expo-router, similar to next.js api routes.

To fetch data on the client, I use React Query (@tanstack/react-query) together with Eden, an Elysia companion from which I get full end-to-end type safety between the API and the app — no manual types or duplication. One repo, fully typed, from database to UI.

What’s next?

100cims continues to grow — the new "Plans" feature (with internal chat per group) is already helping hikers organize their adventures together. And the next update will bring a fully interactive map view for discovering mountains near you.

Future updates will focus on:

  • Gamification features (badges, titles, awards).
  • Challenge creation by the community.

Try the app

If you love hiking, climbing, or just want to follow the journey:

Explore the solution:

This app started as a way to fix a personal failure. But now it’s something that others use, love, and build real memories with. If you’ve ever wanted to build something from scratch with Expo — you can.

This summer I'll reach the summit. And I hope some of you will get there with me.

Expo Router
NativeWind
ElysiaJS
DrizzleORM

Accelerate building apps with Expo and AI

Learn more