This is a clone of the NYT Connections Game. Which itself seems to be an unacknowledged clone of the British game Only Connect.
Anyways..
- Node.js 20 or higher (
.nvmrcfile included fornvmusers)
cd react-connections-game
npm install --legacy-peer-deps
npm run dev# Build and run locally
docker-compose up
# Or use pre-built image from GitHub Container Registry
docker-compose -f docker-compose.simple.yml upThe app will be available at http://localhost:3000
npm start- Start development server (alias fornpm run dev)npm run dev- Start development server with hot reloadnpm run build- Build for productionnpm test- Run tests in watch modenpm run test:run- Run tests once (CI mode)npm run test:ui- Open Vitest UI for visual test explorationnpm run storybook- Start Storybook for component development (requires .jsx refactoring)npm run build-storybook- Build static Storybook sitenpm run format- Format code with Prettiernpm run format:check- Check code formattingnpm run clean- Remove all build artifacts and dependencies
- React 19
- Tailwind CSS
- React Spring for animations
- Shadcn/ui for primitive components
- Vitest + React Testing Library for testing
- Storybook for component documentation
- Copied a number of utility functions from a React Wordle Clone - cwackerfuss/react-wordle
- Built with Parcel
- Dockerized with multi-stage builds (Node 20 + nginx)
- Global state (game status, guesses, etc.) is handled using React's Context API. The provider components are in
src/providers - Components are in
src/components- Primitive components imported from
shadcn/uilibrary and lightly edited are insrc/components/ui - The
Sparklescomponent is taken from Josh Comeau's article on creating animated sparkles in React..
- Primitive components imported from
- Helper functions for local storage, game statistics, and constants are in
src/lib- The actual puzzle data for changing the content of each puzzle is in
src/lib/data.js
- The actual puzzle data for changing the content of each puzzle is in
- Custom hooks are in
src/hooks- Both of these are code snippets taken from Josh Comeau's Blog
This project includes a GitHub Actions workflow that automatically:
- Runs format checks with Prettier
- Executes the test suite with Vitest
- Builds the application
- Builds and publishes Docker images to GitHub Container Registry (on main branch)
All checks run on every pull request to ensure code quality.
Tests are written using Vitest and React Testing Library:
npm test # Watch mode for development
npm run test:run # Run once (used in CI)
npm run test:ui # Visual test interfaceStorybook is configured for component documentation and interactive development:
npm run storybook # Start Storybook dev server (port 6006)
npm run build-storybook # Build static Storybook siteComponent stories available:
WordButton- Interactive word selection button with multiple scenariosButton- All button variants and sizes from the design systemBadge- Badge variants with game status examples
Storybook includes:
- Visual component library for isolated development
- Accessibility checks via @storybook/addon-a11y
- Automatic documentation generation
- Integration with Vitest for component testing
This app includes built-in support for performance monitoring and analytics:
The app automatically tracks Core Web Vitals metrics:
- LCP (Largest Contentful Paint) - Loading performance
- INP (Interaction to Next Paint) - Responsiveness
- CLS (Cumulative Layout Shift) - Visual stability
- FCP (First Contentful Paint) - Initial render
- TTFB (Time to First Byte) - Server response time
In development mode, these metrics are logged to the console. In production, they can be sent to your analytics provider.
The following game events are automatically tracked:
- Game lifecycle:
game_won,game_lost - Player actions:
guess_submitted,guess_correct,guess_incorrect - UI interactions:
shuffle_clicked,deselect_clicked,view_results_clicked,share_score_clicked,info_modal_opened
The analytics system is provider-agnostic. To enable analytics in production, add one of the following to your HTML:
Google Analytics 4:
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'GA_MEASUREMENT_ID');
</script>Plausible Analytics:
<script defer data-domain="yourdomain.com" src="https://plausible.io/js/script.js"></script>Custom Analytics:
// Set your analytics instance on window object
window.analytics = {
track: (event, properties) => {
// Your custom tracking implementation
},
page: (path) => {
// Your custom page view tracking
}
};All analytics code is located in src/lib/analytics.js and src/lib/performance.js for easy customization.
- PuzzGrid which allows you to create your own games/puzzles, no code required.
- Connections Generator by swellgarfo which also allows you to create your own games/puzzles, no code required.
Please fork and submit a PR if you'd like!
Development Requirements:
- Node.js 20+ (use
nvm useif you have nvm installed) - Run
npm install --legacy-peer-depsto install dependencies - Run
npm testwhile developing to ensure tests pass - Run
npm run formatbefore committing to maintain code style - All PRs must pass CI checks (formatting, tests, build)
- your fork here!
Want to add one to the list? Please make a pull request.
