Every sudoku site I've ever used has the same two problems: ads everywhere, and a mouse-only UI that makes fast solving feel clunky. I play sudoku to think, not to fight with my browser.
So I built my own. It's called Kodiak Sudoku — free, no ads, keyboard-first, with vim bindings and a leaderboard that doesn't lie. Here's what went into it.
The stack
- Next.js 15 with the App Router
- React 19
- TypeScript throughout
- Supabase for the database (auth, leaderboard storage, daily puzzle state)
- Drizzle ORM on top of Supabase
- Tailwind CSS
- Vercel for hosting + Edge Config for feature flags
Nothing exotic — just a stack I could move fast with and trust in production.
The three things I actually cared about
1. Free with no ads
This sounds simple but it shapes every decision. No ad SDK to load, no layout shift, no third-party trackers. The page is fast because there's nothing slowing it down. I'm covering hosting costs out of pocket for now — Vercel and Supabase's free tiers go surprisingly far for a side project at this scale.
2. Keyboard-first, with vim bindings
Most sudoku sites are built for mouse/touch. Clicking individual cells is fine on mobile, but on desktop it's slow. I wanted to navigate the board the way I navigate everything else — with hjkl, or arrow keys, or number keys to fill in digits instantly.
The input handling ended up being one of the more interesting parts of the build. React's synthetic event system and the browser's native focus behavior don't always agree, especially when you're trying to make a grid feel like a text editor. Getting vim-style navigation to feel snappy without fighting the DOM took a few iterations.
If you're into this kind of thing — keyboard-driven UIs, focus management, accessibility — I'd love to hear how you've solved similar problems.
3. Honest leaderboards
This one bugged me about every other sudoku leaderboard I've seen: hint-assisted times compete directly against pure runs. Someone who used three hints finishing in 4 minutes shouldn't outrank someone who solved it clean in 5.
Kodiak separates the two. Pure runs and hint-assisted runs are ranked independently. It's a small thing but it changes how the leaderboard actually feels — it's something you can be proud of, not just a number.
Interesting technical bits
Daily puzzle state at the edge
The daily puzzle is the same for everyone, every day. I'm using Vercel Edge Config to store and serve the active puzzle, which means the puzzle data is globally distributed and available with essentially zero latency. State per-user (progress, timer, hints used) lives in Supabase.
Drizzle + Supabase
I'd used Prisma before and wanted to try Drizzle. The type inference is excellent and the query builder feels closer to writing SQL, which I prefer. The integration with Supabase was smooth — I'm using Supabase for auth and RLS policies, with Drizzle handling the query layer.
Puzzle generation vs. curation
I ended up curating puzzles rather than generating them on the fly. Generated puzzles can technically be valid but feel mechanically similar. Hand-selected (or at least filtered) puzzles have more character. For the daily puzzle specifically, I wanted something people would actually enjoy solving, not just a valid grid.
What I used Claude for
Claude was my pair-programmer throughout. Not in a "it wrote the whole thing" way — more like having a senior dev available to rubber-duck architecture decisions, catch edge cases in my input handling logic, and help me move faster on the parts I found tedious (writing marketing copy, mostly).
The parts that required actual judgment — how to structure the leaderboard, how to handle timer state across tab visibility changes, how to make the keyboard UX feel right — those were conversations, not prompts. Worth being honest about the difference.
What's next
The site is live now at kodiaksudoku.com. Daily puzzles, leaderboards, full keyboard support including vim bindings.
Things I'm thinking about for v2:
- Mobile experience improvements (touch is functional but not delightful yet)
- Puzzle difficulty ratings based on solving technique, not just time
- A "practice mode" for specific techniques (naked pairs, X-wing, etc.)
- A Loom walkthrough once I've seen how real users actually play
If you build keyboard-first apps, care about honest UX, or just play a lot of sudoku — I'd genuinely love to hear from you. What would make this better?
Built with Next.js, Supabase, Drizzle, Tailwind, and Vercel. Pair-programmed with Claude.

Top comments (1)
Hey dev.to — maker here.
A decision I almost made differently: generating puzzles algorithmically vs. curating them. Generation is the obvious technical choice, and I built it, but the puzzles felt samey. Switched to curation for the daily and haven't looked back — there's something about a puzzle that was actually selected that makes it feel worth solving.
The thing I'm least happy with right now is mobile touch. It works, but it doesn't feel good the way the keyboard UX does on desktop. If anyone's built a grid-based input experience that felt genuinely delightful on touch, I'd love to know how you approached it.
And if you play sudoku — come try the daily. Leaderboard is real and ad-free is permanent.