# Polymatch: a self-hosted World Cup 2026 prediction pool built on Next.js and Prisma

> Polymatch is a multiplayer prediction game for the 2026 FIFA World Cup: 104 match scorelines, a knockout bracket derived from those picks, and a leaderboard. It is a Next.js 16 app you host yourself against PostgreSQL 17.

**insanekrishnna/polymatch** — https://polymatch.online

- Repository: https://github.com/insanekrishnna/polymatch
- Website: https://polymatch.online
- Stars: 609 · Forks: 11
- Language: TypeScript
- License: not declared
- Published: 2026-09-17 · Updated: 2026-09-17 · Language: en
- Canonical page: https://hysenlabs.com/projects/insanekrishnna-polymatch

## The problem Polymatch solves: a private World Cup pool without a spreadsheet

A World Cup prediction pool usually starts in a group chat and ends in a spreadsheet. Someone collects scorelines by message, someone else maintains a table, and the scoring rules live in one person's head. Polymatch replaces that with a web application where each participant submits predictions for all 104 matches, the knockout bracket is generated from those predictions, and a leaderboard applies a scoring system the README describes as transparent and visible to users.

The audience is narrow and specific. It is for a group of friends or colleagues who want their own pool rather than a public one, and who have someone willing to run a Node.js application and a PostgreSQL database. The README calls it a personal project and invites suggestions through Issues or pull requests, which tells you the intended deployment is a single instance for a known group, not a multi-tenant service.

Scope is fixed to one tournament. The features list covers 12 groups of 4 plus knockout stages, individual awards for Top Scorer, Top Assist, Best Player, Best Goalkeeper, Champion and Runner-up, and an official calendar with venues, times and timezones. There is no mention of a second tournament, a generic competition model, or an import path for other fixtures.

## How Polymatch works: Next.js App Router, Prisma, and a bracket derived from picks

The stack is conventional and the repository layout makes the data flow easy to trace. Routes live under src/app: fixtures for the schedule, predictions for user picks and the bracket, ranking for the leaderboard, admin for tournament results and awards, and api for route handlers including NextAuth. Shared code sits in src/lib (prisma, session, datetime) and src/types.

Persistence is PostgreSQL 17 through Prisma 7, with the data model in prisma/schema.prisma and versioned migrations in prisma/migrations. The tournament data itself is not fetched at runtime: prisma/fifa-data.ts holds the official FIFA 2026 data, and prisma/seed.ts loads it. That is the key architectural decision. Teams, groups and matches are seeded rows, so the schedule is deterministic and the app does not depend on an external fixtures API staying up during the tournament.

The bracket is computed rather than entered. The README states the knockout bracket is generated from your predictions, running from the Round of 32 to the Final. That means a participant's group-stage scorelines determine who advances in their own bracket. Scoring is applied on the leaderboard, and the admin panel is where real results and awards are recorded, which is what turns predictions into points. Authentication uses NextAuth v5 with the Prisma adapter and username plus password, so accounts live in the same database as everything else.

One detail worth noting for anyone deploying across regions: src/lib contains a datetime utility and the calendar advertises timezones. Kickoff times are a real source of bugs in a pool where people in different countries submit picks against the same deadline.

## Installing Polymatch and submitting a first prediction

The README gives a six-step install. Prerequisites are Node.js 20 or newer, PostgreSQL 17 running locally or remotely, and npm (or pnpm, yarn, bun). Clone, install, copy the environment template, migrate, seed, and start the dev server:

```bash
git clone https://github.com/DavidSepulvedaCh/Polymatch.git
cd Polymatch
npm install
cp .env.example .env
npm run db:migrate
npm run db:seed
npm run dev
```

The install step triggers prisma generate through a postinstall hook, so the Prisma client exists before you run anything else. The seed step is the one that matters most: it loads teams, groups and matches from the official FIFA data file, and without it the fixtures and predictions pages have nothing to show.

Two environment variables are documented, and only two: DATABASE_URL, the PostgreSQL connection string used by Prisma, and NEXT_PUBLIC_SITE_URL, the canonical public site URL without a trailing slash, which the README says is used for SEO metadata, sitemap.xml, robots.txt and OpenGraph. Set it wrong and the generated metadata points at the wrong host, which matters in production and not at all in local development. The README points to .env.example as a template for both.

With the server running, open http://localhost:3000, register an account through the login or register routes, and go to the predictions area. From there you enter scorelines for the group matches, and the bracket fills in from those picks. The ranking route shows the leaderboard, which stays empty of real points until someone enters actual results through the admin panel. A production build follows the same shape: provision PostgreSQL, set both variables in the target environment, run prisma migrate deploy as a pre-build step, then npm run build && npm start. The README notes the app is optimized for Vercel but runs on any Node.js-compatible platform.

## Where Polymatch gets awkward: single-tournament data, admin trust, and an unverified licence

The tournament data is hardcoded. prisma/fifa-data.ts is described as official FIFA 2026 data, and the seed script loads it. That is a strength for reproducibility and a limitation everywhere else: if a team list, group draw or kickoff time changes, the fix is an edit to a TypeScript file plus a reseed, not a configuration change. There is no documented admin flow for editing the schedule, only for results and awards.

Results entry is manual and centralized. The admin panel is the only documented path for tournament results and awards, and the leaderboard depends on it. If the person running the instance stops entering results, scoring stalls for everyone. The README does not describe automated result ingestion, nor does it document what happens to predictions after a match has started.

The licence is a genuine open question. The README carries an MIT badge and a License section stating the project is distributed under MIT, but the repository metadata available here records the licence as unknown, and the top-level entries are only FIFAWORLDCUP2026/ and README.md. The README itself says to see LICENSE for more information. Before you build anything on top of this, confirm that file is present and what it contains. The README also carries a trademark disclaimer: FIFA and FIFA World Cup are FIFA property and the project is not officially affiliated with or endorsed by FIFA. That is a naming and branding constraint, not a technical one, and it is worth reading as written.

Finally, the README is candid that this is a personal project. There are no releases recorded, and the last push to the default branch was on 2026-07-02. For a tournament that runs in 2026, that timing is the thing to weigh: you are adopting a codebase at a point in its life, not a product with a support commitment.

## Polymatch versus a generic prediction platform

The obvious alternative is a hosted prediction or office-pool platform, where you create a competition, invite people by link and never touch a database. The difference in approach is ownership of the data and the scoring rules. A hosted platform keeps your participants' accounts and picks on its infrastructure and applies its scoring model; Polymatch keeps everything in your PostgreSQL instance, applies a scoring system the README says is transparent and visible to users, and lets you read prisma/schema.prisma to see exactly how a prediction is stored.

That trade cuts both ways. Self-hosting buys you control over the bracket logic and the ability to change scoring in code, at the cost of running migrations, seeding data, configuring NEXT_PUBLIC_SITE_URL correctly, and being the person who enters results. A hosted platform costs you that control and usually some money, and gives you uptime and support in return.

There is a third option worth naming: a spreadsheet plus a messaging group. It is genuinely adequate for a pool of five people who all know each other. Polymatch becomes worth its operational cost when the group is large enough that manual bracket tracking produces arguments, or when you want the bracket generated from picks rather than assembled by hand. Below that threshold, the install and deploy steps are more work than the problem deserves.

## Maintenance, upgrades and what the licence means for forks

The repository is not archived, and its last push was on 2026-07-02. That is the only maintenance signal available here; there are no recorded releases, so there is no versioned upgrade path to follow. Practically, an upgrade means pulling the default branch, running npm install, applying new Prisma migrations with npm run db:migrate in development or prisma migrate deploy in production, and rebuilding. The README does not document rollback, database backup, or a downgrade procedure, so if you deploy this you should treat the database as something you back up yourself before each migration.

The dependency set is the real maintenance surface: Next.js 16, React 19, TypeScript 5, Tailwind CSS 4, Prisma 7, NextAuth v5, Zod 4. Major versions across a framework, an ORM and an auth library move independently, and a project with no release cadence gives you no signal about when those bumps happen. Budget for reading diffs rather than changelogs.

On licensing, the README states MIT and points to a LICENSE file, while the repository metadata here records the licence as unknown. MIT, if that is what the file says, is permissive: it allows commercial use, modification and redistribution with the licence and copyright notice retained. It does not grant rights to FIFA trademarks, and the README explicitly disclaims affiliation. If you fork this for a public pool, the branding question is separate from the code licence and is not something the repository resolves for you. This is not legal advice; read the actual LICENSE file and the trademark disclaimer before you publish anything.

## Conclusion

Adopt Polymatch if you want a private prediction pool for the 2026 World Cup and you are comfortable running a Next.js app with a PostgreSQL database, since the README documents migrations, a seed script and a Vercel-oriented deploy path. Do not adopt it if you need a hosted service with no operations work, or if you expect a stable multi-season product: the repository is a personal project with a single tournament's data baked into prisma/fifa-data.ts, and the README does not document rollback, upgrade procedures or data retention. Before committing, verify the licence file actually exists in the repository, confirm the Prisma schema matches the FIFA data model you need, and check that the seed script runs cleanly against a fresh database.

## FAQ

### What is Polymatch and who is it for?

Polymatch is a multiplayer web application for predicting the FIFA World Cup 2026. Participants predict scores for all 104 matches, build a knockout bracket from those predictions and compete on a leaderboard. The README describes it as designed for playing with friends.

### How do I install Polymatch?

The README lists Node.js 20+ and PostgreSQL 17 as prerequisites, then clone the repository, run npm install, copy .env.example to .env, run npm run db:migrate, run npm run db:seed and start with npm run dev. The app is then available at http://localhost:3000.

### Which environment variables does Polymatch need?

The README documents two: DATABASE_URL, the PostgreSQL connection string used by Prisma, and NEXT_PUBLIC_SITE_URL, the canonical public site URL without a trailing slash, used for SEO metadata, sitemap.xml, robots.txt and OpenGraph.

### Does Polymatch come with the World Cup 2026 fixtures already?

Yes. The README lists npm run db:seed as loading official FIFA data for teams, groups and matches, sourced from prisma/fifa-data.ts. Until the seed runs, the fixtures and predictions pages have no tournament data to display.

### What licence is Polymatch released under?

The README states the project is distributed under the MIT licence and points to a LICENSE file, though the repository metadata available here records the licence as unknown. The README also notes the project is not officially affiliated with or endorsed by FIFA.

## Sources

- [insanekrishnna/polymatch on GitHub](https://github.com/insanekrishnna/polymatch)
- [Issues](https://github.com/insanekrishnna/polymatch/issues)
- [Project website](https://polymatch.online)
- [README](https://github.com/insanekrishnna/polymatch/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/insanekrishnna-polymatch
