https://github.com/totokartonio/next-arcade
Mini arcade in Next.js 15 (App Router, SSR). Hangman, Snake, Matching Pairs. TypeScript, Zustand, Vitest/Cypress, sound.
https://github.com/totokartonio/next-arcade
app-router arcade css-modules cypress games hangman memory-game nextjs react snake ssr turbopack typescript vitest zustand
Last synced: about 1 month ago
JSON representation
Mini arcade in Next.js 15 (App Router, SSR). Hangman, Snake, Matching Pairs. TypeScript, Zustand, Vitest/Cypress, sound.
- Host: GitHub
- URL: https://github.com/totokartonio/next-arcade
- Owner: totokartonio
- License: mit
- Created: 2025-07-05T17:46:40.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2025-09-04T17:54:17.000Z (about 1 month ago)
- Last Synced: 2025-09-04T19:33:49.582Z (about 1 month ago)
- Topics: app-router, arcade, css-modules, cypress, games, hangman, memory-game, nextjs, react, snake, ssr, turbopack, typescript, vitest, zustand
- Language: TypeScript
- Homepage: https://next-arcade.netlify.app/
- Size: 13.7 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Next Arcade
A collection of small classic games built with [Next.js](https://nextjs.org), featuring Hangman, Snake, and Matching Pairs with immersive sound effects and responsive design.
## Games
- **Hangman** – Guess the word before you run out of attempts
- **Snake** – Classic snake game with keyboard and touch controls
- **Matching Pairs** – Memory card game with pixel art icons and timer## Features
- **Immersive Audio** – sound effects across interactions, plus a global **mute** toggle
- **Mobile Responsive** – touch-friendly controls and layouts optimized for small screens
- **Retro Design** – pixel-inspired arcade aesthetic
- **Fast Performance** – built on **Next.js 15** and **React 19** using the App Router
- **Three Difficulty Levels** – Easy, Medium, and Hard for each game
- **TypeScript** – fully typed for better development experience
- **Tested** – Unit (Vitest) and E2E (Cypress) tests cover core flows## Quick Start
### Prerequisites
- Node.js 18+
- npm, yarn, or pnpm### Installation
1. **Clone the repository**
```bash
git clone https://github.com/yourusername/next-arcade.git
cd next-arcade
```2. **Install dependencies**
```bash
npm install
```3. **Start development server**
```bash
npm run dev
```4. **Open your browser**
Navigate to [http://localhost:3000](http://localhost:3000)## Available Scripts
```bash
# Development
npm run dev # Start development server with Turbopack
npm run build # Build for production
npm run start # Start production server
npm run lint # Run ESLint# Testing
npm run test # Run unit tests with Vitest
npm run test:ui # Run tests with UI
npm run test:coverage # Generate coverage report
npm run test:watch # Run tests in watch mode# E2E Testing
npm run cypress:open # Open Cypress UI
npm run cypress:run # Run Cypress tests headlessly
npm run e2e # Run E2E tests against production build
npm run e2e:dev # Run E2E tests against dev server
```## Game Controls
### Hangman
- **Desktop**: Click letters or use physical keyboard
- **Mobile**: Touch virtual keyboard### Snake
- **Desktop**: Arrow keys or WASD
- **Mobile**: Touch D-pad controls### Matching Pairs
- **Desktop**: Click cards or use Tab + Enter/Space
- **Mobile**: Touch cards## Technical Architecture
### Tech Stack
- **Framework**: Next.js 15 with App Router
- **Frontend**: React 19, TypeScript
- **Styling**: CSS Modules with CSS Variables
- **State Management**: Zustand
- **Audio**: use-sound library
- **Testing**: Vitest + Cypress
- **Build Tool**: Turbopack (dev) / Webpack (prod)### Project Structure
```
src/
├── app/ # Next.js App Router pages
│ ├── arcade/[game]/ # Dynamic game routes
│ ├── about/ # About page
│ └── layout.tsx # Root layout
├── components/ # Shared components
│ ├── ui/ # UI primitives (MagicButton)
│ ├── GameSelector/ # Game selection interface
│ ├── GameOver/ # Game over screen
│ └── ...
├── features/ # Game-specific code
│ ├── hangman/ # Hangman game logic
│ ├── snake/ # Snake game logic
│ └── matchingPairs/ # Memory game logic
├── hooks/ # Custom React hooks
├── stores/ # Zustand stores
├── styles/ # Global styles
├── utils/ # Utility functions
└── types.ts # Global TypeScript types
```### Key Features Implementation
#### Audio System
- Global mute/unmute functionality via Zustand store
- Context-aware sound effects (hover, click, win, lose, etc.)
- Lazy-loaded audio files for performance#### Mobile Support
- Responsive design with CSS media queries
- Touch-optimized controls for Snake game
- Mobile detection hook for conditional UI#### Game State Management
- Custom hooks for each game's logic
- Consistent game status types (`idle`, `running`, `won`, `lost`)
- URL-based difficulty selection with fallbacks## Testing
### Unit Tests (Vitest)
```bash
npm run test # Run all tests
npm run test:coverage # Generate coverage report
npm run test:ui # Interactive test UI
```### E2E Tests (Cypress)
```bash
npm run e2e:dev # Test against dev server
npm run e2e # Test against production build
```### Test Coverage
- Game logic and state management
- Component rendering and interactions
- User workflows and edge cases
- Mobile and desktop experiences## Configuration
### Custom Fonts
The project uses Google Fonts loaded via Next.js:
- **Monoton**: Logo and headers
- **Press Start 2P**: Game titles
- **VT323**: Body text (retro monospace)### Asset Optimization
- SVG icons processed with SVGR
- Images optimized with Next.js Image component## Customization
### Styling
- CSS Variables defined in `src/styles/globals.css`
- Component-scoped styles using CSS Modules
- Responsive breakpoints: 525px, 768px, 1900px, 2560px## Browser Support
- **Modern browsers** (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+)
- **Mobile browsers** (iOS Safari 14+, Chrome Mobile 90+)
- **Features used**: CSS Grid, Flexbox, CSS Variables, ES2017+## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Acknowledgments
### Graphics
- Pixel icons by [Admurin](https://admurin.itch.io/)
- 3D "Magic Button" design by [Josh W. Comeau](https://www.joshwcomeau.com/animation/3d-button/)### Code Inspiration
- Snake game implementation inspired by [Menard Maranan's tutorial](https://dev.to/menard_codes/i-built-a-snake-game-in-react-48b6)
### Audio
- Sound effects from [Freesound.org](https://freesound.org) (Creative Commons)
- Audio playback powered by [use-sound](https://www.npmjs.com/package/use-sound)See more detailed acknowledgments on the **About** page.
## Links
- **Repository**: [GitHub Repository](https://github.com/totokartonio/next-arcade)
---
## Dev Notes
This project was a small playground to experiment with different ideas — primarily **Next.js** and **SSR**. I also wanted to practice **Zustand**, so the global **mute** is powered by it (arguably overkill for a single toggle, but that was the point of the exercise). In general, I consider sound an essential part of arcade games, so adding SFX felt important.
Things I’d still like to add:
- Theme switching (light/dark)
- Scorekeeping in each game
- Local leaderboardsMaybe I’ll circle back and ship these later. I really enjoyed creating this project and hope at least someone on the web has fun messing with it 😅