I’ve participated in hackathons. I’ve also helped organize them.
And I kept seeing the same problems.
Judging could feel inconsistent. Connectivity could become a bottleneck. Organizers were forced to stitch together forms, spreadsheets, messages, and separate tools just to run one event.
So I started building HackNext.
Not because I wanted another project to submit.
I wanted to build the platform I would eventually use to organize my own hackathons.
And then building it taught me something: the difficult part wasn’t building the dashboard.
It was handling everything that happens when the assumptions break.
The architecture decision that shaped everything
The specification required the platform to work in a self-hosted environment without relying on cloud services.
So instead of building around managed authentication, hosted databases, or external APIs, we designed the entire system around:
React + Express + PostgreSQL + Docker Compose + local storage.
The goal became simple:
«If the internet disappears, the core hackathon operation shouldn’t disappear with it.»
That decision affected authentication, storage, certificates, backups, deployment, and even frontend dependencies.
Then judging exposed a bigger problem
One thing I had personally noticed in hackathons was how differently judges can score.
One judge might give projects:
“60, 65, 70, 75, 80”
while another might use:
“85, 90, 92, 95, 98”.
Simply averaging those scores assumes the judges use the scale in the same way.
They don’t necessarily.
We almost shipped a simpler scoring approach before realizing this.
So HackNext uses per-judge score normalization to reduce the effect of differences in scoring range and style.
Then we found the edge case:
What if a judge gives every project exactly the same score?
Standard deviation becomes zero.
Our beautiful formula suddenly has a division-by-zero problem.
We explicitly handled the zero-variance case instead of pretending it wouldn’t happen.
That was a bigger lesson than the formula itself:
«A scoring algorithm isn’t finished when the normal case works. It’s finished when you’ve decided what the abnormal cases mean.»
The Docker problem that looked stupid afterward
We also learned that:
“Docker containers are running” does not mean “the application is ready.”
PostgreSQL could be running but not ready to accept connections.
The API could start before migrations completed.
Seeding could race against database initialization.
It worked on our machine.
Then a clean deployment exposed the assumptions.
Health checks, startup ordering, migrations and deterministic seeding became part of the product — not just deployment configuration.
The “simple” part of the specification
Judge assignment.
Initially:
«Projects + judges = distribute them.»
Then we had to answer:
- How many judges should evaluate each project?
- What if there aren’t enough judges?
- What is the maximum workload per judge?
- Can the requested judging depth actually be achieved?
- Can we reproduce the same assignment when debugging?
We ended up treating feasibility as a mathematical constraint rather than letting the system produce a bad assignment.
That changed how I approached the rest of the platform.
What I actually learned
The hardest part of HackNext wasn’t React.
It wasn’t PostgreSQL.
It wasn’t Docker.
It was turning vague assumptions into rules that the backend could enforce and an organizer could explain.
A hackathon platform isn’t just:
Register → Submit → Judge → Results.
It’s everything that happens when:
- the network fails,
- judges score differently,
- a deadline passes,
- a configuration is impossible,
- a user tries to access something they shouldn’t,
- or an edge case the developer never considered finally happens.
That’s why I’m building HackNext.
Not just to submit a project to a hackathon, but to eventually run better hackathons with it.
