Munchscene is a fairness-first group dining app.
Instead of pure majority voting, it scores restaurant options across all members, applies fairness penalties, and returns a ranked shortlist with AI explanations.
- Create a room and share a 6-character code
- Join a room with live multiplayer updates
- Edit preferences in real time
- Run a fairness-based resolver
- See ranked restaurant results
- Review elimination reasons from hard constraints
- Read AI-generated explanations for top picks
- Frontend: React + Vite + TypeScript
- Backend: Node.js + Express + TypeScript
- Realtime data: Firebase Realtime Database
- Places data: Google Places API
- AI explanations: OpenRouter (Gemini model)
- Monorepo workspaces:
client,server,shared
client/ React app (Vite)
server/ Express API
shared/ Shared types + scoring contracts
npm installCreate .env in the repo root from .env.example:
cp .env.example .envFill in all required values.
npm run dev:clientnpm run dev:serverFrontend defaults to http://localhost:5173.
Backend defaults to http://localhost:8080.
From repo root:
npm run dev:client- run Vite frontendnpm run dev:server- run Express server withtsx watchnpm run build- build all workspacesnpm run typecheck- typecheck all workspaces
Use the exact keys from .env.example.
VITE_APP_NAMEVITE_API_BASE_URLVITE_FIREBASE_API_KEYVITE_FIREBASE_AUTH_DOMAINVITE_FIREBASE_DATABASE_URLVITE_FIREBASE_PROJECT_IDVITE_FIREBASE_STORAGE_BUCKETVITE_FIREBASE_MESSAGING_SENDER_IDVITE_FIREBASE_APP_ID
PORT(optional, defaults to8080)CLIENT_ORIGIN(optional, defaults tohttp://localhost:5173)FIREBASE_PROJECT_IDFIREBASE_CLIENT_EMAILFIREBASE_PRIVATE_KEY(keep newline escapes:\n)FIREBASE_DATABASE_URLGOOGLE_PLACES_API_KEYOPENROUTER_API_KEYOPENROUTER_MODEL(optional, defaults togoogle/gemini-2.5-flash)
Any static frontend host + Node backend host works.
Minimal production requirements:
- Deploy
clientand setVITE_API_BASE_URLto your backend URL. - Deploy
serverand setCLIENT_ORIGINto your frontend URL. - Configure all required env vars from
.env.exampleon each platform.
The client currently writes room state directly to Realtime Database.
If your RTDB rules are locked down, room creation/join may fail with
permission-denied.
For demo environments, ensure rules allow app writes to:
rooms/*roomsByCode/*results/*
Server exposes:
GET /healthPOST /rooms/:roomId/resolve
Run:
npm installCheck Realtime Database rules and ensure write access for your current setup.
Set CLIENT_ORIGIN on the server to your frontend domain.
- Abhinav Badesha
- Binod Dayal
- Dilshan Dadrao
- Jeevan Bhullar