Tech Stack Overview

Every technology choice in Vivolar with the rationale behind it.

tech-stack spring-boot react postgresql

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.