My Side Project Stack in 2026
I’m currently working on two projects alongside my day job, each with a different stack. One is a fun experiment I built with AI, the other is a SaaS product. Here’s what I’m using and what I’ve learned so far.
The two projects
Cyprus Payroll 2026 — A Vue 3 web app for Cyprus tax compliance that I built as a fun experiment with AI-assisted development. Replaces my old Excel spreadsheet with a type-safe payroll calculator. Fully static, no backend.
ParkMyAWS — A SaaS that helps teams schedule and park unused AWS resources to cut costs. Full-stack Laravel + React app, still in development. What matters for this article is the stack choices.
Two very different products, two different stacks, but some shared principles.
Backend: Laravel 12
ParkMyAWS runs on Laravel 12 with PHP 8.5. After 9+ years with Laravel, it’s still my go-to for anything that needs a backend. The ecosystem is mature, the conventions are solid, and I can move fast without fighting the framework.
What I’m using heavily:
- Action classes for business logic (no fat controllers, no fat models)
- Queues for all external API operations—you can’t have third-party API calls blocking HTTP requests
- Laravel Cashier + Paddle for subscriptions
- PHPStan level 9 with 100% type coverage—this catches bugs that tests miss
The Action pattern has been the single biggest improvement to how I write Laravel code. Every meaningful operation is a standalone class with a handle method. I wrote about this in detail here.
Frontend: Vue 3 vs React 19
Cyprus Payroll uses Vue 3 with Composition API. ParkMyAWS uses React 19 with Inertia.js.
I went with Vue 3 for the payroll app because I wanted something lightweight—no backend, no SSR, just reactive UI on top of pure TypeScript functions. Vue’s Composition API with <script setup> is clean and productive. Pinia for state management is simple and type-safe.
React 19 powers ParkMyAWS via Inertia.js, which gives me server-driven navigation with a React frontend. Laravel + Inertia is a natural fit—you get the benefits of an SPA without building a separate API.
If I’m honest, both work well. Vue feels lighter for standalone apps. React has a bigger ecosystem when you need specialized components (data tables, charts). I don’t think the framework matters as much as people argue—TypeScript strict mode on both is what actually prevents bugs.
TypeScript: strict mode everywhere
This is the one non-negotiable across both projects. TypeScript in strict mode with no implicit any.
On the PHP side, PHPStan level 9 serves the same purpose. Between the two, I have full type coverage across every line of code in both projects.
Is it slower to write? A bit, at first. But I’ve lost count of how many times the type checker caught something that would have been a runtime error.
Styling: Tailwind CSS 4
Both projects use Tailwind CSS 4 (the new Oxide engine). I use shadcn components on both—shadcn-vue for Cyprus Payroll, shadcn/ui for ParkMyAWS.
Tailwind 4 simplified the config (just @import "tailwindcss" in your CSS). The @theme directive for custom values is cleaner than the old tailwind.config.js approach. Dark mode works out of the box.
shadcn is the right level of abstraction for me—copy-paste components that I own and can modify, rather than a heavy component library with opinions I’ll fight later.
Testing: Vitest + Pest
Vitest for the Vue/TypeScript side. Pest PHP for Laravel. Both are fast and expressive.
My coverage targets: 90% minimum overall, 100% for critical business logic. The tax calculator has caught real bugs at bracket boundaries that manual testing would’ve missed, so this isn’t just a vanity metric.
Build & deploy
- Vite for both frontends (it’s the default for both Vue and Laravel now)
- Vercel for Cyprus Payroll (static deploy, free tier)
- Standard VPS for ParkMyAWS (Laravel needs server-side execution)
- GitHub Actions for CI/CD on both
The common thread
Across both projects, the things that matter most are the same:
- Strict types—TypeScript strict + PHPStan level 9
- Pure functions for core logic—tax calculations, cost calculations, anything that needs to be testable
- Pre-commit quality gates—formatting, linting, type-checking, and tests all run before every commit
- Boring tech, well-executed—no bleeding-edge dependencies, no over-engineering
The best stack is the one where you spend your time building features instead of fighting your tools.