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.