Full-stack React Native + Next.js travel app with Hono API, Prisma, MSW mock layer, and 68 commits in a week

After leaving Prachyam I gave myself ten days to build something with no constraints, no client brief, and no one else's opinion in the room. I'd been thinking about travel apps for a while — not because I travel constantly, but because the problem space is genuinely hard: offline maps, itinerary state that survives bad connectivity, media that needs to live somewhere. I wanted to work through all of it at once.
That pressure is what produced 68 commits, 127,000 lines of code, and a production Android APK in ten days. I'm not listing those numbers to brag — I'm listing them because they represent a specific kind of decision: to build wide instead of deep, to ship 155+ features in three days as MVP and then layer infrastructure on top. It was a deliberate call, and it had real tradeoffs I'll come back to.
The scope grew from a single question: what would a travel app actually need to be useful, not just interesting? Itinerary planning is obvious, but itineraries need to survive airplane mode. Maps need to work offline. Photos need to go somewhere — which meant MinIO for object storage, not just uploading to a placeholder. Real-time notifications made sense because travel involves other people and changing plans.
By the end I had four independently deployable surfaces: a React Native mobile client, a Next.js web frontend, a Next.js admin panel, and a Hono API server handling all of them. The Prisma schema hit 1,060 lines across 30+ models. WebSocket notifications were live. Docker Compose orchestrated Postgres, Redis, and MinIO locally. The Android APK was 143 MB and it ran.
None of that happened by accident. I had a list of what I wanted the system to demonstrate and I worked through it systematically. The architecture decisions — Hono over Express because of its first-class TypeScript ergonomics and edge compatibility, TanStack Query for all server state because optimistic updates and cache invalidation are genuinely hard problems — were made early and held throughout.
This is the one I'm most pleased about in retrospect. Mobile development without a mock layer means you're constantly waiting: waiting for the backend to be ready, waiting for the real API to return test data, waiting for network conditions you can't control in a simulator. I've worked on teams where this slowed everyone down and nobody questioned it because it was just how things worked.
I questioned it. MSW — Mock Service Worker — intercepts network requests at the handler level and returns realistic fixture data. It meant the React Native client could be developed and tested with full data fidelity before the Hono API was complete. More importantly, it meant the two surfaces could evolve independently without one blocking the other.
The implementation takes discipline to maintain — mock handlers drift from real API contracts if you're not careful, and in a solo sprint the temptation is to skip the mock and just hit the real endpoint. I didn't skip it, because the upfront cost of maintaining the mock layer is always cheaper than the debugging cost when real network conditions surface problems you didn't anticipate.
127,000 lines across 246 files sounds like a metric you'd put on a CV and hope nobody probes. So let me probe it myself.
Some of it is generated — Prisma migrations, type definitions, build artifacts that ended up in the count. Some of it is boilerplate that any serious full-stack mobile project accumulates: config files, environment schemas, Docker definitions. The ratio of novel decision-making to scaffolding is probably 30/70, which is normal for this kind of project.
What the volume does represent accurately is surface area covered. Four deployable surfaces. A complete auth flow. Media uploads. WebSocket infrastructure. Offline map handling. An admin panel. A mock layer. Docker orchestration. These are not toy implementations — they're the real decisions, the ones that bite you in production.
The honest caveat is polish. At sprint pace, you make the feature work and move on. Error states are handled but not beautiful. The UI has rough edges that a second week would have fixed. I made the tradeoff consciously: I wanted to demonstrate architectural judgment across the full stack, and a tightly polished three-screen app wouldn't have done that. Whether that was the right call depends on what you value. I know what I was building for.
Did this resonate?