Game Snippets — Free HTML CSS JS Playable Browser Games
40 playable games · Snake, Pong, 2048, Minesweeper, Sudoku, Wordle-style word games, plus coding games for CSS, regex & binary · Exports to React, Vue, Angular & Tailwind
What's included
Features
About this tool
Game Snippets — Free Playable Browser Games in Vanilla JavaScript, With the Non-Obvious Logic Done Right
Most "game" snippets on the web are screenshots — a static mockup of a Wordle board, a Sudoku grid that accepts any digit, a Tic-Tac-Toe opponent that clicks at random. Every game in this collection is genuinely playable, with real logic underneath: the 15-puzzle only ever shuffles into solvable states, the Wordle-style scorer handles repeated letters correctly, Minesweeper flood-fills empty regions, and the Sudoku board is generated by actual backtracking. All of it is plain HTML, CSS, and vanilla JavaScript with no engine, no canvas library, and no build step.
The collection splits into five groups. Arcade and reflex covers Snake, Pong, Breakout, a flappy-style dodger, Whack-a-Mole, a rhythm tapper, and dodge-the-blocks — the classic game-loop exercises. Board and logic covers Tic-Tac-Toe with a real heuristic opponent, Connect Four, Battleship, Minesweeper, a 6x6 mini Sudoku, the 15-puzzle, 2048-style tile merging, a maze runner, and a colour-sort puzzle. Word and number covers a Wordle-style guesser, Hangman, word search, word unscramble, quick maths, number guessing, and hex colour guessing. Skill tests covers typing speed, reaction time, and click speed. And a learn-to-code set turns programming itself into the game: writing CSS selectors, flexbox properties, regular expressions, shell commands, and binary place values to clear levels.
The logic is correct, not merely plausible
Each of these games has one detail that most from-scratch implementations get wrong, and each snippet specifically gets it right. A naive Wordle scorer double-credits repeated letters, so guessing ERASE against CRANE marks both E's yellow when the target holds only one; the correct scorer runs two passes over a shared consumption array. A purely random 15-puzzle shuffle is unsolvable about half the time because permutation parity is a real mathematical constraint, so the shuffle replays legal moves from the solved state instead. A naive Tic-Tac-Toe "AI" picks a random empty cell; this one takes a win, blocks a loss, then prefers centre, corners, and edges. The sorting puzzle scores you against the provable minimum derived from permutation cycle decomposition, not a guessed par.
Game loops, timers, and the right clock
Continuous games run on requestAnimationFrame so movement stays tied to the display refresh rather than a fixed interval, while turn-based and countdown games use setInterval deliberately and clear it on every state change. Reaction and typing tests measure with performance.now() rather than Date.now(), because it is high-resolution and immune to system clock adjustments — the same API browser profiling tools use internally. Whack-a-Mole shows the self-rescheduling randomised timer pattern, where each pop schedules its own retract and then the next pop, with a single active-hole reference as the source of truth for what is clickable right now.
Input that works with a mouse, a finger, and a keyboard
Grid and drag games use pointer events with setPointerCapture, so one code path serves mouse, touch, and stylus, and a drag that leaves the element still tracks. Games with both on-screen controls and keyboard shortcuts route every input through a single handler function, so validation and win-checking exist in exactly one place regardless of how the move arrived. Canvas games convert coordinates through getBoundingClientRect, which is what keeps hit detection correct when CSS displays the canvas at a size other than its backing resolution.
Games that teach programming, graded on behaviour
The learn-to-code set is built on a deliberate principle: grade what the player's answer does, not how they spelled it. The CSS selector game runs your selector through the browser's own querySelectorAll and compares the matched element set; the regex game specifies each level as strings that must match and strings that must not, so any pattern satisfying the specification passes; the flexbox game detects a win by measuring positions with getBoundingClientRect rather than comparing property names; the logic gate puzzle evaluates all eight rows of a truth table rather than the switches currently on screen. Any correct route to the answer is accepted, which is what builds real understanding instead of memorisation.
Persistence, cleanup, and framework export
Games with a best score write to a single, clearly-named localStorage key and only rewrite it when the record actually breaks. Every game manages its own timers and clears them on reset, which matters when you export to React, Vue, or Angular: mirror that cleanup in your unmount lifecycle so a game left running in an unmounted component does not keep firing. Every snippet exports to React, Vue, Angular, and Tailwind in one click from its page.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
Every one is fully playable in the browser with real logic underneath — Snake moves and grows, Minesweeper flood-fills empty regions, the Sudoku board is generated by backtracking, and the Tic-Tac-Toe opponent genuinely tries to win and block. You can play each one in the live preview on its page before copying a single line of code.
No. Every game is plain HTML, CSS, and vanilla JavaScript with no dependency and no build step. A few use the native canvas element or the Web Audio API directly, but nothing pulls in Phaser, PixiJS, or any other library — copy the three panels into your project and it runs.
Ten of them: the CSS Selector Challenge, Flexbox Alignment Game, Regex Match Game, Binary Bit Flip Game, Predict the Output Quiz, Bug Hunt Game, Robot Loop Programmer, Terminal Command Game, Sorting Swap Puzzle, and Logic Gate Puzzle. Each grades behaviour rather than exact wording, so an unanticipated but correct answer still clears the level.
The logic does, but the cleanup is on you. Each game starts its own setInterval or requestAnimationFrame loop and clears it on reset; when you port one, mirror that cleanup in the unmount lifecycle (a useEffect return in React, onUnmounted in Vue, ngOnDestroy in Angular) so a game left running in an unmounted component stops firing. Best scores use localStorage under a single named key, so if you embed several games on one page check the keys do not collide.
Yes — the tunable values are named constants at the top of each script rather than magic numbers buried in the logic. Board dimensions, tick speed, countdown length, clue counts, and word lists are all single-line edits, and the games that generate their board (Sudoku, the 15-puzzle, the maze) derive everything from those constants so changing one rebuilds the game correctly.