Tech Stack Overview
Every technology choice in Vivolar with the rationale behind it.
Backend
Spring Boot 3.5 + Java 21
Why: Spring Boot is the industry standard for Java web applications. Java 21 brings virtual threads, pattern matching, and records — modern language features that reduce boilerplate without sacrificing type safety.
Alternatives considered: Kotlin + Ktor (too niche for a portfolio piece), Node.js/Express (weaker type safety, less mature ORM ecosystem for complex domains).
JPA/Hibernate + Flyway
Why: JPA provides a clean abstraction over SQL with type-safe queries. Flyway ensures database schema evolves in a controlled, versioned, repeatable way. Together they make the data layer both productive and reliable.
Key decision: Forward-only migrations. Never manipulate flyway_schema_history. To revert, create a new migration. This avoids the dangerous pattern of ad-hoc DDL in production.
MapStruct
Why: Compile-time DTO mapping. No reflection overhead, full type safety, and generated code that’s easy to debug. When a field is added to an entity, MapStruct forces you to handle it in the mapper — at compile time, not runtime.
PostgreSQL 16
Why: Battle-tested relational database with excellent JSON support, full-text search, and a rich ecosystem. Running via Docker Compose locally, managed instance in production (Railway).
Spring Security + OAuth2 + JWT
Why: Google OAuth2 for authentication (no password management), JWT tokens for stateless API authorization. The security layer is centralized in the common package with household-scoped data access enforced at the service layer.
Frontend
React 19 + TypeScript
Why: React is the most widely adopted UI library with the largest ecosystem. TypeScript adds compile-time type safety that catches errors before they reach the browser. React 19’s server components and concurrent features keep the architecture modern.
Vite
Why: Fast dev server with HMR (Hot Module Replacement), native ESM support, and minimal configuration. Build times are measured in seconds, not minutes.
Tailwind CSS
Why: Utility-first CSS that keeps styles co-located with components. No context switching between CSS files, no naming debates, and the generated CSS is tiny after purging.
Key decision: Using Tailwind for the portfolio site too, keeping the skill set consistent.
react-router (not react-router-dom)
Why: The project uses react-router directly — this is a deliberate choice documented in the codebase conventions. It’s the modern approach recommended by the library authors.
Infrastructure
Railway
Why: Simple deployment with PostgreSQL hosting, auto-deploys from git branches, environment management, and health checks. Configuration lives in railway.toml and nixpacks.toml files (IaC).
GitHub Actions
Why: CI/CD integrated with the repository. Backend and frontend pipelines run independently, both must pass before merging.
Docker Compose
Why: Local development environment that matches production. One command (docker compose up -d) starts PostgreSQL with the right version, extensions, and initial configuration.
AI / LLM Integrations
GPT-4o-mini (via OpenAI API)
Used for: Product categorization, photo scanning (vision), voice command parsing, and the AI chat assistant. Chosen for cost-effectiveness and sufficient quality for these tasks.
Claude Code (Development)
Used for: AI-assisted development — implementation, testing, documentation, and deployment automation. Integrated via CLAUDE.md project instructions, custom skills, and automated hooks.