Vim Royale: The Project I Kept Postponing Until I Finally Shipped It
This is a submission for the GitHub Finish-Up-A-Thon Challenge
What I Built
Vim Royale is a competitive PvP Vim editor game where you can practice, improve, and go head-to-head with friends.
The idea is straightforward: two players get the same broken code snippet and race to fix it using Vim motions in a real editor. First one to finish wins.
What started as "just a Vim game" turned into a full competitive platform with:
- Realtime gameplay
- Match replays
- Tournament creation and invites
- Live spectator mode
- Vim keybindings import (including
.vimrc-style mappings)
The stack under the hood:
| Layer | Tech |
|---|---|
| Frontend | React + TypeScript (Vite) + CodeMirror + Vim mode |
| Backend | Go + Gin + WebSockets/SSE |
| Database | PostgreSQL |
| Infra | Docker |
Live app: vimroyale.com
Demo: YouTube
The Comeback Story
I had this idea sitting in my head since last year.
My first attempt was in Elixir/Phoenix, and I actually got pretty far by February. But integrating npm-heavy editor tooling in that stack kept slowing me down. I was writing too many JS hooks just to make basic UI and editor pieces work. Slowly, momentum faded.
A few weeks ago I made a decision: stop overthinking and just finish it.
I switched to a stack that had less friction for this kind of project:
- React for frontend flexibility and the npm ecosystem
- Go + Gin for a clean and predictable backend
- Postgres for match, tournament, and user data
- Docker to keep setup simple and reproducible
That switch changed everything.
React made npm integration painless. CodeMirror became a huge unlock for the editor-focused gameplay. Once that foundation was solid, I could actually focus on building features instead of fighting the framework:
- WebSocket-based realtime match flow
- Match replay playback from stored keystroke data
- Live spectate streams
- Tournament lobbies, seeding, and event updates
- Custom Vim keymap import, preview, and save
Vim Royale finally became the game I had pictured from day one.
Working with GitHub Copilot
Copilot helped me most in the places where momentum usually dies: repetitive scaffolding, context switching, and debugging confusing errors.
A few places it genuinely made a difference:
Day-to-day autocomplete
It sped up implementation across React components and Go handlers, especially when I was wiring similar state, props, or API shapes over and over again.
Generating boilerplate
Scaffolding component structures and helper logic got faster, which made it easier to go from an idea to a working version without losing steam.
Single-player mode starter code
Copilot gave me useful snippets I could adapt instead of building everything from scratch.
Understanding unfamiliar React patterns
This was my first serious React project. Copilot helped me understand new patterns and debug errors without constantly breaking flow to dig through documentation.
The useEffect double-fire mystery
This one was a real time sink. useEffect was running twice in development but not in production. Copilot pointed me toward React Strict Mode behavior, which saved me from chasing completely the wrong bug for hours.
Copilot did not build it for me. But it kept me moving when I would have otherwise slowed down or stopped.
Closing Thoughts
Vim Royale means something to me because I've been using vim for the last 4 years and always wanted to make a game around it.
Stack indecision and life getting in the way delayed this for a long time. Finishing it taught me something simple: the best stack is usually the one that keeps you moving. Once I accepted that, everything clicked.
If you enjoy Vim, competition, and coding games, give it a try and let me know what to build next.
Top comments (1)
would love y'all's feedback on vim royale!
check it out at vimroyale.com