A free, real-time multiplayer online party game inspired by Cards Against Humanity. Play with friends from any device with an internet connection.
Based on: yusufameri/cards-against-humanity
New contributors: read the Repository Guidelines for structure, tooling, and workflow expectations.
- React 18 with TypeScript
- Vite - Fast build tooling and HMR
- Socket.IO Client - Real-time game communication
- React Router - Client-side routing
- React DnD - Card drag-and-drop interactions
- Vitest - Unit and component testing (119 tests)
- Node.js (≥18.0.0) with Express
- Socket.IO - Real-time bidirectional communication
- Redis - Session storage and game state management
- TypeScript - Type safety throughout
- Winston - Structured logging
- pnpm - Package management with workspaces
- Redis Adapter - Horizontal Socket.IO scaling support
- Session-based authentication with Redis store
- Rate limiting and security middleware
- Node.js ≥18.0.0 (recommend using nvm)
- pnpm - Install globally:
npm install -g pnpm - Redis - Running locally or accessible instance
git clone <repository-url>
cd cards-against-humanity
pnpm install# Server configuration
cp server/.env.example server/.env
# Edit server/.env with your settings
# Client configuration (optional)
cp client/.env.example client/.envRequired environment variables:
SESSION_SECRET- Secure random string for session signingALLOWED_ORIGINS- Comma-separated CORS origins (e.g.,http://localhost:5173)PORT- Server port (default: 8080)NODE_ENV-developmentorproduction
# macOS with Homebrew
brew services start redis
# Or run directly
redis-server# Start both client and server with hot reload
pnpm dev
# Or run separately
pnpm dev:client # Frontend on http://localhost:5173
pnpm dev:server # Backend on http://localhost:8080- Install Tilt (
brew install tiltor follow https://tilt.dev) and start Docker Desktop (the Redis helper runs as a container). - Run
tilt upfrom the repo root to launch the Vite client, Socket.IO backend, and an auto-started Redis container. If you already have Redis running elsewhere, disable theredisresource in the Tilt UI. - Use
tilt trigger lintortilt trigger testsfor one-off checks, and runtilt downwhen you're done to stop all resources.
pnpm buildpnpm build:client # Outputs to client/dist
pnpm build:server # Outputs to server/distcd server
pnpm start # Runs compiled JS from dist/pnpm lint # Runs ESLint for both workspaces (fails on warnings)
pnpm --filter pc_ui lint # Lint client only
pnpm --filter pc_api lint # Lint server only# Run all client tests
pnpm test:client
# Watch mode for development
cd client
pnpm test:watch
# Coverage report
pnpm test:coverage
# Interactive UI
pnpm test:uiClient test coverage: 119 passing component tests
# Run all server tests
pnpm test:server
# Watch mode for development
cd server
pnpm test:watch
# Coverage report
pnpm test:coverage
# Interactive UI
pnpm test:uiServer test coverage: 68 passing tests
- 10 authentication middleware tests
- 35 card routes API tests
- 23 Socket.IO event handler tests (validation & game flow)
# Run both client and server tests
pnpm testTotal test coverage: 187 tests (119 client + 68 server)
cards-against-humanity/
├── client/ # React frontend (Vite)
│ ├── src/
│ │ ├── components/ # React components
│ │ ├── pages/ # Route pages
│ │ ├── hooks/ # Custom React hooks
│ │ └── utils/ # Client utilities
│ └── dist/ # Production build output
│
├── server/ # Express + Socket.IO backend
│ ├── src/
│ │ ├── routes/ # REST API routes
│ │ ├── services/ # Business logic (GameService, CardService)
│ │ ├── models/ # Data models
│ │ ├── middleware/ # Express middleware
│ │ ├── utils/ # Server utilities
│ │ └── index.ts # Server entry point
│ └── dist/ # Production build output
│
└── scripts/ # Utility scripts
├── submit-cards.sh # Card submission tool
└── example-cards.json # Sample card data
- Real-time multiplayer game rooms
- Card Czar rotation system
- Drag-and-drop card selection
- Live scoring and winner announcement
- Mobile-optimized interface
User-generated card submission and moderation system:
Submission Endpoints:
POST /api/cards/submit- Submit single cardPOST /api/cards/batch- Batch submit (up to 100 cards)
Moderation Endpoints (requires moderator role):
GET /api/cards/pending- View cards awaiting approvalPOST /api/cards/approve/:id- Approve cardPOST /api/cards/reject/:id- Reject card with optional reason
Authentication Endpoints:
GET /api/cards/auth/role- Check current user's rolePOST /api/cards/auth/promote- Promote to moderator (requiresADMIN_KEY)
Query Endpoints:
GET /api/cards/approved- List approved user cardsGET /api/cards/:id/stats- Card usage statisticsGET /api/cards/expansions- Available card packs
Command-line submission tool:
# Submit single card
./scripts/submit-cards.sh -s "Your card text" A
# Batch submit from JSON
./scripts/submit-cards.sh -b scripts/example-cards.json1,322official cards from base game and expansions- Support for user-generated cards (pending moderation)
- Redis-backed session management
- Rate limiting for abuse prevention
- Full Deployment Guide - Complete Docker setup for Digital Ocean
- CI/CD Setup - Automated deployment on push to main
-
Environment Configuration
- Set strong
SESSION_SECRET - Set strong
ADMIN_KEYfor moderator promotion - Configure
ALLOWED_ORIGINSfor your domains - Set
NODE_ENV=production - Configure
LOG_LEVEL=infoorwarn
- Set strong
-
Redis Setup
- Ensure Redis is accessible from your server
- Consider Redis persistence configuration
- Optional: Redis Cluster for horizontal scaling
-
Build and Deploy
pnpm install --production=false pnpm build # Serve client/dist/ with static file server (nginx, CDN, etc.) # Run server with: cd server && pnpm start
-
Security Considerations
- Enable HTTPS/TLS in production
- Configure appropriate CORS origins
- Review rate limiting thresholds
- Moderation endpoints protected with role-based authentication
- Keep
ADMIN_KEYsecret and rotate periodically - Regular Redis backups for game state
- Redis Adapter enables horizontal Socket.IO scaling
- Multiple server instances can share Redis for session/game state
- Consider load balancer for multi-instance deployments
For detailed game rules, see the official Cards Against Humanity rulebook.
Basic Rules:
- One player is the Card Czar each round
- Card Czar reads a question card (black)
- Other players submit their funniest answer card (white)
- Card Czar picks the best answer
- Winner gets a point, Card Czar rotates
- First to reach point goal wins
License: MIT (software) / CC BY-NC-SA 2.0 (game content)
Based on: Cards Against Humanity by Cards Against Humanity LLC
Original Project: yusufameri/cards-against-humanity
Disclaimer: This is a fan-made project not affiliated with, endorsed by, or sponsored by Cards Against Humanity LLC. Cards Against Humanity game content is licensed under Creative Commons BY-NC-SA 2.0. This project is for educational and personal use only. Do not use for commercial purposes.