A real-time posture monitoring web app that uses your webcam and machine learning to detect bad posture and alert you with sound notifications.
- Start tracking — click Start to activate your webcam and initialize the ML body-pose model.
- Baseline capture — the first detected eye position becomes your "good posture" reference point.
- Continuous monitoring — every 250 ms the app compares your current head position against the baseline.
- Alerts — if your posture drifts beyond configurable thresholds (looking up or slouching down) for a sustained period, you hear an audio alert.
- Settings panel — adjust all thresholds, intervals, and sound parameters in real time via the settings panel beside the video feed.
- Next.js 15 (Pages Router) — React framework
- React 19 — UI rendering
- XState 4 — finite state machine drives the tracking lifecycle
- ml5.js (MoveNet) — browser-based body-pose estimation
- react-webcam — webcam access
- Tailwind CSS 3 — styling
# Install dependencies (legacy-peer-deps needed for @xstate/react + React 19)
npm install --legacy-peer-deps
# Start the dev server
npm run devOpen http://localhost:3000 and click Start.
| Command | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
Production build |
npm start |
Start production server |
npm test |
Run unit tests (Jest + React Testing Library) |
npm run test:watch |
Run unit tests in watch mode |
npm run test:coverage |
Run unit tests with coverage report |
npm run test:e2e |
Run end-to-end tests (Playwright) |
npm run test:e2e:headed |
Run e2e tests in headed browser |
This app is designed for desktop browsers only. Here's why:
- Webcam positioning — posture detection relies on a stable, front-facing camera at roughly eye level. Laptops and desktop monitors provide this naturally; phones and tablets do not.
- ML model performance — MoveNet body-pose estimation is computationally intensive. Desktop CPUs/GPUs handle the continuous inference loop (4 detections/second) much more reliably than mobile processors.
- Browser API support — persistent
getUserMediawebcam access, Audio autoplay, and canvas rendering perform most consistently on desktop Chrome, Firefox, and Edge. - Screen real estate — the video feed, canvas overlay, status panel, and settings panel are laid out side by side, requiring a landscape viewport.
pages/ → Next.js pages (index, _app)
src/
constants.js → Default thresholds, intervals, sound URLs
machine.js → XState state machine
services.js → ml5 initialization + pose detection
utils.js → Utility functions
settings-context.jsx → React context for runtime settings
components/
fix-posture.jsx → Main component (webcam + canvas + controls)
fix-posture-wrapper.jsx → Restart wrapper + settings provider
settings-panel.jsx → Settings UI
status.jsx → Collapsible debug panel
actions/ → XState action handlers
helpers/ → Pose-to-position extraction
__tests__/ → Jest unit tests
e2e/ → Playwright end-to-end tests
public/sounds/ → Alert sound files
MIT