A real-time multiplayer party game inspired by Cards Against Humanity and Apples to Apples. One player draws a prompt card, everyone else plays their funniest response, and the selector picks a winner. First to the target score wins.
- Players join a room using a 4-letter code
- Each player gets 7 white cards
- Every round, one player is the selector who draws a black (prompt) card
- Everyone else picks a white card from their hand to play
- The selector sees cards flip over one by one, picks their favorite, and awards a point
- First to 5 points wins (configurable)
- Real-time multiplayer via WebSockets (Socket.IO)
- Custom decks — upload your own cards as a JSON file
- Card flip animations with staggered reveal
- Live submission tracking — the selector sees face-down cards arrive in real time
- Built-in default deck — works out of the box, no card file needed
- Mobile friendly
- Frontend: React + Vite + Tailwind CSS
- Backend: Node.js + Express + Socket.IO
- Deployment: Docker / Railway
- Node.js 18+
- npm
git clone https://github.com/YOUR_USERNAME/this-is-fun.git
cd this-is-fun
npm run install:allnpm run devThis starts both the server (port 3001) and client (port 5173) concurrently. Open http://localhost:5173 in your browser.
You'll need at least 3 players to start a game. Open multiple browser tabs or have friends join from their devices on the same network.
The easiest way to get this running on the internet. Costs ~$5/month or less for a party game with occasional use.
- Clone this repo to your account, or download and push to a new repo
- Sign up at railway.com with your GitHub account
- Click New Project → Deploy from GitHub Repo → select this repo
- Railway auto-detects the Dockerfile, builds, and deploys
- Once deployed, go to Settings → Networking → Generate Domain to get your public URL
That's it. Railway handles HTTPS, port mapping, and auto-redeploys on every push to main.
Custom domain: In Railway's service settings, add your domain and point a CNAME record to the provided Railway hostname.
Build and run locally or on any server with Docker:
docker build -t this-is-fun .
docker run -p 3001:3001 this-is-funOpen http://localhost:3001. The Node server serves both the API and the built React app.
If you prefer compose:
docker compose up -d --buildThe app will be available on port 8080.
The host can upload a custom deck in the lobby before starting the game. The file should be a JSON file with this structure:
{
"blackCards": [
"Why is _ always so fun?",
"_ + _ = disaster"
],
"whiteCards": [
"A rubber duck",
"Existential dread",
"Free WiFi"
]
}Requirements:
- At least 5 black cards
- At least 20 white cards
- All card values must be strings
- Use
_as a placeholder in black cards for where the white card answer goes
If no custom deck is uploaded, the game uses a built-in default deck.
├── Dockerfile # Production build (Railway / Docker)
├── docker-compose.yml # Local Docker Compose setup
├── railway.json # Railway deployment config
├── shared/
│ └── constants.js # Shared enums and config
├── server/
│ ├── index.js # Express + Socket.IO server
│ ├── gameManager.js # Game state and logic
│ └── deck.js # Card shuffling + default deck
├── client/
│ ├── index.html
│ └── src/
│ ├── App.jsx
│ ├── context/
│ │ └── GameContext.jsx
│ └── components/
│ ├── Home.jsx
│ ├── Lobby.jsx
│ ├── GameBoard.jsx
│ ├── GameOver.jsx
│ ├── FlipCard.jsx
│ └── CardImport.jsx
└── nginx/
└── default.conf # Nginx config (Docker Compose only)
Do whatever you want with it. It's fun.