Building Snake in 2025 shouldn't need a framework. No React, no Vue, no Three.js — just HTML, CSS, and plain JavaScript. This is a love letter to that approach, and a documentation of what we learned doing it.
The Challenge of "Simple"
The hardest part of building this Snake game was not implementing the game logic — that took an afternoon. The hardest part was making it feel good. Smooth movement, responsive controls, satisfying feedback, beautiful visuals — the gap between "working" and "polished" is where most of the work lives.
The Game Loop Architecture
We use a delta-time accumulator pattern that decouples update speed from render speed. This means the snake moves at a consistent speed regardless of whether the browser is running at 60fps or 144fps. It also means we can increase the snake's speed by simply decreasing the update interval — no changes to the game logic required.
Mobile First, Desktop Too
Touch controls are deceptively tricky. A swipe needs a minimum distance threshold (we use 10px) to avoid registering accidental touches. The swipe direction calculation needs to consider whether the horizontal or vertical component is dominant. And crucially, swipes need to be blocked when a modal is open so users can scroll through content without accidentally steering the snake.
Web Audio Synthesis
We generate sound effects with the Web Audio API — no audio files required. The "eat" sound is a sine oscillator ramping from 520Hz to 880Hz over 120ms. The "die" sound is a sawtooth oscillator descending from 300Hz to 60Hz over 300ms. These two sounds took maybe twenty minutes to tune, and they add enormous emotional feedback to the game.
- Vanilla JS is more than capable — frameworks are a choice, not a requirement
- Polish takes more time than architecture, and it's worth every minute
- Mobile controls need careful tuning — don't skip the edge cases
- Synthesised audio is a superpower that most web developers ignore