For the core team
Travelita’s technical stack, release stages, and cost
A technical document outlining the tech stack, development stages, and operational costs involved in developing the Travelita platform.
Travelita has to recommend trips that actually make sense: where to go, when to go, what to eat, what to do, how to get there, where to stay, roughly how much it costs, and what other people said. It’s a website, and it has to feel fine on multiple devices.
The development roadmap is divided into several simple stages: local development, limited release, initial public launch, subscription and payment implementation, and further growth based on demand.
Same stack, added slowly
Next.js, NestJS, PostgreSQL, R2, and MapLibre from day one. Later stages only add hosting, cache, a domain, then payments.
The product has to work locally
PostGIS, a curation CMS, seasons, maps, auth, and search before we deploy. An empty catalogue still looks like an empty page, no matter how nice the server is.
Hold the expensive stuff
Auth0, OpenSearch, Kubernetes, Google Maps as the main map, and an LLM as the ranking engine can wait. MapLibre and Postgres will take us a long way.
Early development
Four steps of development cost
Each step adds a layer, but we don’t swap the stack.
When each layer turns on
Stack matrix
| Layer | 1.1 Local | 1.2 Limited | 1.3 Public | 1.4 Subscribe |
|---|
Operating cost
What we actually pay
The bar scale goes up to Rp7.1 million, the top of a careful growth budget. Early stages sit well below that. Don’t read the last bar as next month’s invoice.
The real bills
- 1.1: nothing.
- 1.2: Railway Hobby at US$5, about Rp89k.
- 1.3: Railway + always-on Neon at US$15–25 + a domain at US$12–15 a year.
- 1.4: no extra servers. Midtrans takes a cut per payment.
Easy to miss
- Vercel Pro is US$20 per person who deploys, not per project.
- Google Maps can cost more than the whole backend.
- Filling the destination catalogue usually costs more than Neon.
Once traffic is actually up
Growth is not a new house
Subscriptions can start in 1.4. “Growth” is capacity: Railway getting tight, the database heavy, search starting to wheeze. We raise one painful thing at a time.
Fine, if we’re actually stuck
- Vercel Pro, Cloud Run / ECS, read replicas, automated backups
- BullMQ for heavier jobs, OpenTelemetry
- Stripe if someone pays from abroad
- OpenSearch only after Postgres search is measured slow
Don’t turn these on “just in case”
- Auth0, Kubernetes, splitting into microservices
- Google Maps or Places as the main data source
- An LLM ranking destinations. It can write the why, not pick the place
- OpenSearch now because “the data will be big later”
What I’m proposing
Decisions for the team
We use this
This is the main stack. Hosting and extras get added by stage; the tools below stay the same.
- Frontend
- Next.js, TypeScript, Tailwind, shadcn/ui, TanStack Query, Zustand — plus an admin CMS in the same app
- Backend
- NestJS, TypeScript, Prisma, REST API, Swagger
- Database
- PostgreSQL with PostGIS, Indonesian full-text search, and pg_trgm. Locally in Docker; later on Neon
- Auth
- Auth.js and Google OAuth on Next.js. NestJS only checks the session or JWT
- Maps & files
- MapLibre for maps. Cloudflare R2 and Sharp for photos. Redis (Upstash) for cache from 1.2
- Hosting
- Vercel for the frontend, Railway for the API, Cloudflare for DNS/CDN once we have a domain
- Ops & payments
- PostHog, Sentry, Resend, and GitHub Actions from 1.2. Midtrans from 1.4
How developers work
We don’t build the whole platform in one go. Work follows the four stages: local first, then a limited release for the core team, then a public launch, then payments. Each stage has a clear job. We only move on when that job is done.
- 1.1 — build Travelita and the admin on local machine until the core product actually works.
- 1.2 — deploy so the core team can try it, still on free URLs.
- 1.3 — put a real domain in front of it and open it to the public.
- 1.4 — add Midtrans only after people are using the recommendations.
This plan can still change
The stack and the cost numbers here are a starting map, not a contract. Later on we may add a tool, drop one, or wait longer before paying for something — depending on what the product actually needs. The bill can go up or down from these estimates.