
Travel · Otrip
Problem
A travel startup needed four things that had to feel like one product: a consumer-facing travel app, a marketing website, an admin panel for operators, and a blog CMS for content. Built separately, they'd drift apart in weeks - different auth, different design language, different data fetching. The brief was one ecosystem, not four codebases wearing the same logo.
Your scope
I led the frontend architecture across all four modules - the shared design system, authentication flow, data-fetching patterns, and the interactive map experience at the heart of the consumer app. One set of conventions, applied four times.
System architecture
Next.js 15 across all four surfaces with a shared component library and design tokens. Global client state lives in Redux Toolkit; server state goes through TanStack Query with aggressive caching for search results and listings. Interactive maps and geolocation run on Mapbox GL. Authentication is a secure multi-step OTP flow; every surface is mobile-first and fully responsive.
Key decisions
- One design system, four consumers. Considered letting each module own its components; rejected - four modules means four chances for the brand to drift. A single token set and component library keeps them coherent.
- Redux Toolkit for client state, TanStack Query for server state. Considered putting everything in Redux; rejected - server state has different needs (caching, refetching, deduping) and TanStack Query handles them better than hand-rolled thunks.
- Mapbox GL for maps, not a wrapper library. The core travel experience is the map - custom markers, geolocation, smooth fly-to transitions. Direct Mapbox GL access keeps that control instead of fighting an abstraction.
Engineering challenges
- Keeping four Next.js surfaces visually and behaviorally consistent without slowing any of them down.
- Map performance on mid-range mobile devices - markers, tiles, and gestures all competing for the main thread.
- A multi-step OTP auth flow that feels instant but stays secure.
Solutions
- Shared design tokens + component library consumed by all four modules; visual changes ship once and land everywhere.
- Mapbox GL with marker clustering and viewport-based rendering - only what the user sees gets drawn.
- TanStack Query caches search and listing data aggressively; repeat visits feel instant.
- Mobile-first responsive layouts throughout; the consumer app is designed phone-first, not adapted later.
Stack
- Frontend - Next.js 15, React 19, TypeScript, Redux Toolkit, TanStack Query, Tailwind CSS
- Maps & geo - Mapbox GL, browser geolocation
- Auth - Multi-step OTP flow
Links
- Live: otrip.io