Hey IH 👋
Yesterday I introduced SpotBooker — my solo-built meeting room booking SaaS. Today I want to go deeper into the tech stack, because I know a lot of you are making these decisions right now.
## The stack
- Backend: Laravel 10 / PHP 8.1+
- Frontend: Vue 3.2 (Composition API) / Tailwind CSS 3.3
- Glue: Inertia.js (no separate API needed)
- Database: MySQL with multi-tenant architecture
- Cache & Queues: Redis
- Payments: Stripe via Laravel Cashier 14 with metered billing
- Email: Mailjet API v3
- Calendar UI: FullCalendar 6 (resource timeline)
- Charts: Chart.js 4
- Auth: Laravel Socialite (Google OAuth)
- i18n: mcamara/laravel-localization (4 languages)
- Hosting: AWS (S3, Redis, the usual)
- Build: Vite 4
## Why Laravel + Vue
As a solo founder, I needed to move fast without sacrificing quality. Laravel gives you so much out of the box — auth, queues, scheduling, mail, payments with Cashier. I didn't have to stitch together 15 different libraries to get a working backend.
Vue 3 with Composition API was a natural fit. The reactivity system is perfect for a booking app where availability changes in real time. Combined with Inertia.js, I get the SPA feel without maintaining a separate API layer. One codebase, one deployment.
Tailwind CSS was a no-brainer for speed. No time spent naming CSS classes or fighting specificity. The whole UI is consistent and responsive without a dedicated designer.
## The decisions I'm happy with
Inertia.js was the best decision I made. No REST API to maintain, no state management hell, no CORS issues. The frontend talks directly to Laravel controllers through Inertia. For a solo dev, this saves an enormous amount of time.
Laravel Cashier with metered billing handles the pricing model cleanly. The base plan includes 8 spots, and additional spots are billed as usage through Stripe. Cashier makes this almost trivial to implement.
Redis for everything — session, cache, queues. One service, three jobs. Queue workers handle email notifications, check-in reminders, and analytics event processing without blocking the main request.
FullCalendar 6 with resource timeline view. Building a calendar from scratch would have taken weeks. FullCalendar handles drag-and-drop, resource grouping, and timezone management. Worth every minute spent learning the API.
## What I'd reconsider
MySQL over PostgreSQL. MySQL works fine, but PostgreSQL's JSON support and full-text search would have been useful for the analytics engine and SpotFinder. Not a dealbreaker, but if I started today I'd go Postgres.
Mailjet. It works, it's reliable, but the API documentation is mediocre and the dashboard feels dated. I'd probably look at Resend or Postmark if starting fresh.
No TypeScript. I started with plain JS in Vue components for speed. Now with 50+ components, I occasionally miss type safety. Adding TypeScript retroactively is painful, so my advice: start w