A browser-based yoga pose coach and timer. It detects poses in real time using TensorFlow MoveNet, times how long the pose is held, and posts scores to a global leaderboard backed by MongoDB. Frontend runs entirely on the client; persistence is via Vercel serverless API.
- Real-time pose detection with MoveNet (client-side, no video upload)
- Timer and best-time tracking per pose
- Global per-pose leaderboard stored in MongoDB
- Responsive UI with React and MUI
- Works with a standard laptop webcam
- Frontend: React (Create React App), TensorFlow.js, MUI
- Pose estimation: MoveNet (SINGLEPOSE_THUNDER)
- Classifier: Small TF.js dense model over normalized keypoints
- Backend: Vercel Serverless Functions (Node.js)
- Database: MongoDB (Atlas recommended) via Mongoose
- Hosting: Vercel
AsanaMeter/
backend/ # Legacy Express server (not used on Vercel)
classification model/ # Training data and scripts (optional)
frontend/ # App root when deploying to Vercel
api/
leaderboard.js # GET /api/leaderboard?pose=...
leaderboard/add-time.js # POST /api/leaderboard/add-time
public/
src/
pages/
Yoga/ # Pose detection, timer, UI
Leaderboard/ # Leaderboard page
package.json
vercel.json # For CRA SPA rewrites (move to frontend/ if project root set there)
- The webcam stream runs locally in the browser.
- MoveNet outputs 17 keypoints per frame (x, y, confidence).
- Keypoints are centered (hips), scale-normalized, and flattened to a 34-dim vector.
- A small TF.js classifier predicts the pose class; when confidence > threshold, the timer runs.
- On stop, a POST request upserts the best time per user/pose.
- The leaderboard page fetches sorted results per pose.
- GET
/api/leaderboard?pose=Vrikshasana- Returns a sorted list of
{ position, name, time }(desc by time)
- Returns a sorted list of
- POST
/api/leaderboard/add-time- Body:
{ userId, name, age, pose, time } - Upserts best time for the user on that pose
- Body:
MONGO_URI(required): MongoDB connection string (Atlas recommended)
Examples:
- Local (dev only):
mongodb://localhost:27017/yogaGameDB - Atlas:
mongodb+srv://<user>:<pass>@cluster.mongodb.net/<db>?retryWrites=true&w=majority
Prereqs: Node 18+, npm; optional local MongoDB if testing DB locally.
- Install dependencies
cd frontend
npm install
# If not already present
npm install mongoose
- Set env var for dev (optional when using local MongoDB)
- On Windows PowerShell (example):
$env:MONGO_URI="mongodb://localhost:27017/yogaGameDB"
- Start the app (CRA dev server + serverless via Vercel CLI optional)
- Simple CRA run (API calls will fail unless deployed or using vercel dev):
npm start
- Recommended: run with Vercel dev to emulate serverless locally
npm install -g vercel
vercel dev
# open http://localhost:3000
- Push your repo to GitHub.
- In Vercel, import the repo and set the Project Root to
frontend/. - Build settings:
- Framework Preset: React (or Other)
- Build Command:
npm run build - Output Directory:
build
- Environment Variables: add
MONGO_URI(Production and Preview). - Ensure serverless functions live in
frontend/api/. - Place
vercel.jsoninsidefrontend/with SPA rewrites:
{
"rewrites": [
{ "source": "/api/(.*)", "destination": "/api/$1" },
{ "source": "/(.*)", "destination": "/index.html" }
]
}
- Redeploy.
- 404 on
/api/...:- Project Root must be
frontend/and functions must be infrontend/api/ - Split endpoints into files:
leaderboard.jsandleaderboard/add-time.js
- Project Root must be
- 500 on API:
- Check Vercel function logs
- Ensure
MONGO_URIis set and reachable (Atlas network access) - Ensure
mongooseis listed infrontend/package.json
- CORS:
- Not needed when frontend and API share the same Vercel domain
From frontend/:
npm start– CRA dev servernpm run build– production buildvercel dev– run frontend and serverless locally
- Add auth (JWT/magic links) to prevent name spoofing
- Validation (Zod) and rate limiting on serverless endpoints
- Connection reuse / pooling patterns in serverless
- Improve classifier and add more poses
MIT