A real-time competitive browser game where 2–4 players race to build the shortest logical word chain between two given words. Each step requires a word and a short explanation; submissions are validated and scored by an AI judge with a resilient provider fallback (Groq → Gemini → Llama 3.3 → basic scorer).
Built with ❤️ by Pratyush — a fun passion project exploring real-time multiplayer and AI-powered gameplay.
- Real-time multiplayer (2–4 players) using Socket.IO
- AI-judged semantic validation and scoring (multi-provider fallback)
- Server-authoritative game state persisted to SQLite
- Lightweight monorepo with separate
frontendandbackendpackages - Guest sessions with persistent UUID stored in
localStorage - REST API endpoints for game management, stats, and administration
- Node.js 18+
- npm 9+
# Clone repository
git clone <repo-url>
cd ChainCrack
# Install dependencies for all packages
npm installStart both packages (monorepo):
npm run devOr run packages individually:
npm --workspace=packages/backend run dev
npm --workspace=packages/frontend run devThe frontend runs at http://localhost:5173 (Vite default). The backend API and Socket server run at http://localhost:5000.
Copy the env examples and fill secrets.
Backend (packages/backend/.env):
PORT=5000
DATABASE_PATH=./gamestate.db
GROQ_API_KEY=your_key_here
GROQ_MODEL=llama-3.1-8b-instant
GEMINI_API_KEY=your_key_here
GEMINI_MODEL=gemini-2.0-flash
LLAMA_API_KEY=your_key_here
LLAMA_BASE_URL=https://api.together.xyz/v1
NODE_ENV=developmentFrontend (packages/frontend/.env):
VITE_API_URL=http://localhost:5000
VITE_WS_URL=ws://localhost:5000Build both packages for production:
npm run buildStart backend in production mode:
npm --workspace=packages/backend startPreview frontend production build:
npm --workspace=packages/frontend previewChainCrack/
├── packages/
│ ├── backend/ # 🔧 Node.js + Express + Socket.IO + SQLite
│ │ ├── src/
│ │ │ ├── server.js # Express app & Socket.IO setup
│ │ │ ├── db/
│ │ │ │ ├── init.js # SQLite initialization & migrations
│ │ │ │ └── queries.js # Raw SQL queries
│ │ │ ├── routes/ # REST API endpoints
│ │ │ │ ├── auth.js
│ │ │ │ ├── games.js
│ │ │ │ ├── players.js
│ │ │ │ ├── stats.js
│ │ │ │ └── leaderboard.js
│ │ │ ├── services/ # Business logic
│ │ │ │ ├── ai/ # Multi-provider LLM validation
│ │ │ │ ├── game/ # Game logic & state management
│ │ │ │ ├── player.js
│ │ │ │ ├── stats.js
│ │ │ │ └── wordService.js
│ │ │ ├── types/ # JSDoc type definitions
│ │ │ └── utils/ # Helper utilities
│ │ ├── .env.example
│ │ └── package.json
│ │
│ └── frontend/ # ⚛️ React + Vite + Tailwind CSS
│ ├── src/
│ │ ├── components/ # Reusable React components
│ │ ├── pages/ # Page-level layouts
│ │ │ ├── Game.jsx
│ │ │ ├── Home.jsx
│ │ │ ├── Lobby.jsx
│ │ │ ├── Leaderboard.jsx
│ │ │ ├── Results.jsx
│ │ │ └── Vote.jsx
│ │ ├── hooks/ # Custom React hooks
│ │ ├── services/ # API & Socket.IO client
│ │ ├── types/ # JSDoc type definitions
│ │ ├── App.jsx
│ │ ├── index.css # Global styles
│ │ └── main.jsx
│ ├── public/ # Static assets
│ ├── index.html
│ ├── vite.config.js
│ ├── tailwind.config.js
│ ├── postcss.config.js
│ ├── .env.example
│ └── package.json
│
├── package.json # Monorepo root
├── README.md # This file
└── LICENSE
- Backend: Single-source-of-truth game state in SQLite, server-authoritative via Socket.IO
- Frontend: React components consuming real-time updates from Socket.IO
- Database: SQLite with raw SQL (no ORM) for full control
- Real-time: Socket.IO events keep all players in sync
- AI Validation: Multi-provider fallback chain (Groq → Gemini → Llama 3.3 → basic scorer)
Run the test suite:
npm run testThis is a personal hobby project built for learning and portfolio purposes. AI validations may not always be accurate and the game may contain bugs.
- Fork the repo and create a feature branch:
feature/your-feature - Follow the commit message style (imperative, lowercase)
- Run tests and linters before opening a PR
- Open an issue to discuss larger changes first