Project overview

duels

Two strangers, one ~90-second head-to-head duel, no install and no account — a web platform where matchmaking, scoring, and every answer reveal run server-side at the edge, so the game stays fast and stays cheat-proof.

Play live at fastduels.com

Stack at a glance

svelte framework better-sqlite3 db/orm drizzle-orm db/orm better-auth auth tailwindcss styling vite build/test vitest build/test
full stack
Production
@better-auth/passkey ^1.6.9@opentelemetry/api ^1.9.1@simplewebauthn/browser ^11.0.0@simplewebauthn/server ^11.0.0canvas-confetti ^1.9.3jose ^6.2.3openskill ^4.1.1partysocket ^1.0.2
Dev
@cloudflare/workers-types ^4.20260502.1@eslint/js ^9.16.0@inlang/paraglide-js ^1.11.0@inlang/paraglide-sveltekit ^0.15.0@playwright/test ^1.49.0@sveltejs/adapter-cloudflare ^7.2.8@sveltejs/kit ^2.10.0@sveltejs/vite-plugin-svelte ^5.0.0@tailwindcss/vite ^4.0.0@types/better-sqlite3 ^7.6.13@types/canvas-confetti ^1.9.0@types/node ^22.10.0drizzle-kit ^0.31.10eslint ^9.16.0eslint-plugin-svelte ^2.46.0globals ^15.13.0jsdom ^26.0.0partykit ^0.0.115prettier ^3.4.0prettier-plugin-svelte ^3.3.0prettier-plugin-tailwindcss ^0.6.0sharp ^0.33.5start-server-and-test ^2.0.12svelte-check ^4.1.0svelte-eslint-parser ^0.43.0tsx ^4.19.2typescript ^5.6.3typescript-eslint ^8.18.0wrangler ^4.87.0

Why this stack

Realtime on Durable Objects, not a socket server

Each match is its own in-memory stateful object at the edge, so there is no global lock and the per-message ping never waits on a database — D1 is touched only at session boundaries.

full decision in the course →

Anonymous-first accounts with Better Auth

Players still just type a nick, but identity lives in a server session from the first touch — so it survives a cache clear or a device switch, and signing in is offered only once there is a win worth saving.

full decision in the course →

A pure-TypeScript engine with zero Cloudflare imports

The same game logic runs in a Worker, a browser, and a Node test unchanged — which is what makes the documented ~one-week migration off Cloudflare credible, and what lets the server replay runs to catch cheaters.

full decision in the course →

The server replays every run; the client score is never trusted

The deterministic engine re-runs the exact rounds from the same seed and scores from scratch, so a client's tally is only a claim to verify — topping the leaderboard still means actually playing a correct game.

full decision in the course →

One GameModule contract every game implements

The platform never imports a specific game, so when multi-choice arrived months later it slotted in as a single new case with the three existing categories untouched.

full decision in the course →

What it gives you

The numbers

Data

LOC, build time, sessions, language split, commit history, and the full file-by-file breakdown.

Why it's built this way

Course

A cinematic „why” course — the architectural decisions, the traps they avoid, and the roads not taken.