A minimalist Snake clone built with React, TypeScript, and HTML Canvas โ focused on mastering game loops, keyboard input, and UI feedback using React hooks and refs.
๐งฉ This project is part of my ongoing React fundamentals journey exploring how to handle real-time loops, keyboard input, and canvas drawing inside React without heavy frameworks.
๐ฅ Gameplay Sneak Peek
๐ Live Demo
Try Snake here: https://snake-beryl-six.vercel.app/
- โก Smooth Canvas Rendering โ real-time updates without unnecessary re-renders
- ๐ฎ Arrow Key Controls โ responsive movement with spacebar restart
- ๐ Dynamic Food Spawning โ random positions, never overlaps the snake
- ๐ฅ Collision Detection โ walls and self-collision instantly end the game
- ๐ Clean Restart Logic โ quick replay loop with instant feedback
- ๐ซ Animated Score Pop โ subtle CSS bump when you eat food
- ๐ Dark Grid Aesthetic โ modern look with subtle borders and Tailwind styling
- ๐ Sound Effects โ satisfying audio feedback for moves, food, and game-over
- ๐งฉ Difficulty Presets โ easy, medium, and hard options that scale board size and speed
- ๐ฅ Emoji Food Items โ random fruits and veggies add playful variety
- ๐พ Persistent Best Score โ keeps your top score across sessions (local leaderboard per difficulty)
- ๐ Celebrations โ confetti on new high score and every 5 points
- โธ๏ธ Pause / Resume Hotkey โ toggle with the
Pkey - ๐งฑ Dynamic Speed Scaling โ snake speeds up as you grow
- ๐งญ Modular Hook Architecture โ reusable logic with
useSnakeGame,useTicker, and friends - โ๏ธ Strict TypeScript + ESLint โ clean, type-safe codebase with zero warnings
Scores are stored locally in your browser. Your best scores per difficulty appear in the Leaderboard from the main menu.
We love contributions of all kinds! Whether itโs fixing a bug, suggesting a feature, or polishing docs, your help makes this game better.
How to join in:
- Fork & open a PR
- Add yourself to Contributors
- Share ideas in roadmap discussions
- Report bugs via Issues
Every contribution, big or small, helps keep this project alive ๐
Check upcoming ideas and milestones in the Project Roadmap.
Snake is a community project, shaped by everyone whoโs played, tested, and contributed.
Every commit, idea, and bug report makes the game better.
Meet all our amazing Contributors
๐ Click to expand project file structure
.
โโโ .github
โ โโโ ISSUE_TEMPLATE
โ โ โโโ bug.yml
โ โ โโโ config.yml
โ โ โโโ documentation.yml
โ โ โโโ enhancement_refactor.yml
โ โ โโโ feature_request.yml
โ โ โโโ question_discussion.yml
โ โโโ workflows
โ โ โโโ snake-ci.yml
โ โ โโโ vercel-production.yml
โ โโโ pull_request_template.md
โโโ .gitignore
โโโ .husky
โ โโโ pre-commit
โ โโโ pre-push
โโโ .prettierignore
โโโ .prettierrc
โโโ .prettierrc.json
โโโ .prettierrc.yml
โโโ .stylelintrc.json
โโโ CONTRIBUTORS.md
โโโ eslint.config.js
โโโ index.html
โโโ package-lock.json
โโโ package.json
โโโ playwright.config.ts
โโโ public
โ โโโ snake.svg
โ โโโ sounds
โ โโโ food.mp3
โ โโโ gameover.mp3
โ โโโ move.mp3
โโโ README.md
โโโ scripts
โ โโโ precheck.sh
โโโ e2e
โ โโโ app.spec.ts
โโโ src
โ โโโ app
โ โโโ App.tsx
โ โโโ assets
โ โ โโโ snake-gameplay.gif
โ โโโ components
โ โ โโโ AchievementsModal.tsx
โ โ โโโ CountdownOverlay.tsx
โ โ โโโ GameOverOverlay.tsx
โ โ โโโ HUD.tsx
โ โ โโโ HowToPlayModal.tsx
โ โ โโโ LeaderboardModal.tsx
โ โ โโโ MenuScreen.tsx
โ โ โโโ MobileControls.tsx
โ โ โโโ SettingsModal.tsx
โ โ โโโ SnakeCanvas.tsx
โ โ โโโ StatsScreen.tsx
โ โโโ constants
โ โ โโโ foodThemes.ts
โ โ โโโ game.ts
โ โ โโโ skins.ts
โ โ โโโ themes.ts
โ โโโ data
โ โ โโโ achievements.ts
โ โโโ hooks
โ โ โโโ useBestScore.ts
โ โ โโโ useCanvas2D.ts
โ โ โโโ useGameScale.ts
โ โ โโโ useGameSession.ts
โ โ โโโ useGameSetup.ts
โ โ โโโ useInput.ts
โ โ โโโ useLeaderboard.ts
โ โ โโโ usePauseHotkey.ts
โ โ โโโ useSettings.ts
โ โ โโโ useSnakeGame.ts
โ โ โโโ useSwipe.ts
โ โ โโโ useTicker.ts
โ โโโ main.tsx
โ โโโ services
โ โ โโโ achievementService.ts
โ โ โโโ achievementService.test.ts
โ โ โโโ statsService.ts
โ โ โโโ statsService.test.ts
โ โโโ styles
โ โ โโโ App.css
โ โโโ types
โ โ โโโ game.ts
โ โ โโโ index.ts
โ โ โโโ ui.ts
โ โโโ utils
โ โโโ canvas.ts
โ โโโ gameTick.ts
โ โโโ haptics.ts
โ โโโ logic.ts
โ โโโ logic.test.ts
โ โโโ seedRandom.ts
โ โโโ share.ts
โ โโโ soundGenerator.ts
โ โโโ speed.ts
โโโ tsconfig.json
โโโ tsconfig.node.json
โโโ vite.config.ts
Requirements: Node 18+
- Clone repo
git clone git@github.com:NickTheDevOpsGuy/Snake.git- Install dependencies
npm install- Start dev server
npm run dev- Run tests (optional):
npm test- In your browser, visit http://localhost:5173
| Name | Version | Description |
|---|---|---|
| React | ^19.x | UI library for building components. |
| Vite | ^7.x | Fast dev server & bundler. |
Run with npm run <script> (see package.json for full list).
| Category | Script | What it does |
|---|---|---|
| Dev | dev |
Start Vite dev server |
build |
Type-check (tsc -b) then build with Vite | |
preview |
Preview the production build | |
| Test | test |
Placeholder test script (exits 0) |
test:watch |
Run Vitest in watch mode | |
| Deploy | predeploy |
Build before deploy |
deploy |
Publish dist/ to GitHub Pages via gh-pages |
|
| Lint/Format | lint |
ESLint for JS/TS (., extensions: js, jsx, ts, tsx) |
lint:fix |
ESLint with --fix |
|
format |
Prettier write across the repo | |
format:check |
Prettier check (no writes) | |
lint:css |
Stylelint for **/*.{css,scss} (includes build output unless ignored) |
|
lint:css:fix |
Stylelint --fix for src/**/*.{css,scss} |
|
| Checks | check |
Run Prettier (write) then ESLint |
check:fix |
Run Prettier (write) then ESLint with --fix |
|
| TypeScript | tscheck |
TypeScript type-check only (no emit) |
| Tooling | precheck |
Run scripts/precheck.sh (project preflight) |
| Git Hooks | prepare |
Run Husky setup on install |
Created with โ, curiosity, and a bit of chaos by Nicholas Clark.
Follow my learning-in-public journey:
GitHub: @NickTheDevOpsGuy โข LinkedIn: @NickDoesDevOps
๐ท #NickDoesDevOpsโ#LearningInPublicโ#BuiltInPublic
