Skip to main content
·Brock

Choosing the Right Tech Stack for GotNext

A deep dive into why I chose Java, Spring Boot, Next.js, and PostgreSQL for a competitive gaming platform.

tech-stackarchitecture

Last week I talked about the high-level vision for GotNext. This week I want to get into the weeds on the tech stack, because I think the choices here matter a lot more than people give them credit for.

Backend: Java + Spring Boot

I know, I know. Java isn't exactly the cool kid at the hackathon. But here's the thing: I'm building a platform that will eventually handle real money. Credits, wagers, tournament prize pools. That means I need strong typing, mature ecosystem support for payments, and battle-tested security libraries.

Spring Boot gives me all of that. Spring Security handles authentication and RBAC. The JPA/Hibernate layer makes database interactions clean. And the ecosystem for things like scheduled tasks (tournament check-in reminders, automated match expiration) is excellent.

I'm using JWT tokens for authentication with refresh token rotation. The security layer enforces role-based access control with players, organizers, admins, and super admins all having different permissions.

Frontend: Next.js + TypeScript + Tailwind

For the frontend, Next.js was a no-brainer. Server-side rendering for SEO (important for public tournament pages and leaderboards), file-based routing, and the App Router for layouts. TypeScript everywhere. I'm not debugging undefined is not a function on a platform that handles competitive matches.

For styling, I went with Tailwind CSS and shadcn/ui as the component library base. shadcn is great because you own the components. They live in your codebase, not in a node_module. I can customize everything without fighting abstractions.

Database: PostgreSQL + Flyway

PostgreSQL handles everything I need: JSONB fields for flexible data (prize pool structures, sponsor logos), proper indexing, and reliable transactions. Flyway manages schema migrations with versioned SQL files, so I always know exactly what the database looks like at any point in time.

I made a rule early on: never edit a migration file that's been deployed. Always create a new one. This has saved me from painful debugging sessions more than once.

Infrastructure: Docker Compose

Locally, everything runs in Docker Compose. One command (make dev) starts PostgreSQL and the backend in containers, with the frontend running locally via npm run dev for hot reloading. For production, I'm deploying to a DigitalOcean droplet with Docker Compose and managing it with Ansible playbooks.

It's not Kubernetes. It doesn't need to be. For a platform at this stage, a single well-configured server with Docker is more than enough, and it's way cheaper than managed container services.

What I'd Reconsider

Honestly, I'm faster and more comfortable in Go. If this were purely about shipping as quickly as possible, I'd have picked Go without thinking twice. But my new job uses Java and Spring Boot, so building GotNext with the same stack is a way to get more familiar with it outside of work. There's no better way to learn a framework than to build something real with it, and the Java ecosystem for payments (Stripe SDK, etc.) and security is hard to beat.

The stack is working well so far. Next time I'll talk about something closer to my heart: the Gears of War community and why they're the first players I'm building for.

    Choosing the Right Tech Stack for GotNext | GotNext.gg