Skip to content
Nothing leaves your device

Count the rep.Then judge it.

Kinetix reads 33 pose landmarks from your camera at frame rate, turns them into joint angles, and counts reps with a hysteresis state machine that does not double-count when you shake. Every rep is scored on range of motion and tempo, with live cues when your form slips.

  • 5 movements
  • No video upload
  • CSV export
  • Works offline once cached
squat · knee angle · live
Reps
12
Knee angle
96°
Chest up, less forward lean
Range of motion, last 12 reps

Illustration of the trainer readout. Open it for live tracking on your own camera.

Validation

The counter is tested, not asserted

A rep counter is easy to demo and easy to get wrong: a naive threshold on a noisy 30 Hz angle trace double-counts almost every rep. So the state machine is checked on every push against synthetic traces with known ground truth, each one modelling a failure mode that actually broke it during development.

TraceWhat it modelsExpectedCountedResult
cleantextbook cadence88pass
noisy±4° jitter88pass
partial40% ROM must not count00pass
pause-at-bottom1.2 s hold mid-rep55pass
micro-bouncetwitching at the top44pass
dropout0.5 s tracking loss66pass
fast-cadence0.8 s reps1010pass
driftrising baseline66pass

8/8 traces exact, plus 5 movement definitions checked for threshold consistency. Generated 2026-07-31 by npm run validate, which CI runs on every push. Frame rate and inference latency are shown live in the trainer rather than quoted here, because they depend on your hardware.

Pipeline

Landmarks in, judgement out

  1. 01

    Landmarks

    MediaPipe BlazePose returns 33 landmarks per frame. The wasm runtime and the model bundle are self-hosted, so no CDN and no upload — the video stays in the tab.

  2. 02

    Pick a side

    Phone cameras are off-axis, so one limb is always half-occluded. Kinetix scores landmark visibility per side and measures the confident one instead of averaging a blurred signal.

  3. 03

    Angles

    The chosen movement reduces to one primary joint angle plus secondary checks (torso tilt, hip line, elbow drift). Angles are smoothed with an EMA that tolerates dropped landmarks.

  4. 04

    Count

    A two-state machine with a hysteresis band. Reps need full travel, at least 45% of target range, and 0.55 s spacing — so jitter, pauses and micro-bounces at the top do not inflate the count.

  5. 05

    Score

    Every rep is stored with tempo, achieved range of motion, peak angle and which form checks fired, then classified good / partial / sloppy.

  6. 06

    Keep

    Sets persist in IndexedDB and export as CSV, one row per rep. No account, no server, no analytics.

Movements

Declarative definitions

Adding a movement is data, not code: a primary joint, two thresholds, a hysteresis margin, a range target and a list of form checks.

Squat

92168°

Knee angle

  • Go deeper — aim for thigh parallel
  • Chest up, less forward lean
  • Keep both feet planted

Push-up

88162°

Elbow angle

  • Straighten your body — hips are sagging or piking
  • Lower further — elbows to 90°

Biceps curl

52155°

Elbow angle

  • Stop swinging — keep the torso still
  • Keep the elbow pinned to your side

Overhead press

78166°

Elbow angle

  • Stop leaning back
  • Finish the lockout

Hip hinge / deadlift

95172°

Hip angle

  • Less knee bend — hinge from the hips
  • Push the hips further back
Limits

What it does not do

  • Single-camera 2D. Angles are measured in the image plane, so a rotated body reads shallower than it is. Stand square to the framing the app suggests.

  • Counting is validated on synthetic angle traces with known ground truth, not on a labelled video corpus. The failure modes covered are jitter, pauses, partial reps, dropouts, fast cadence and baseline drift.

  • Form checks are heuristics on joint geometry, not physiotherapy. They catch gross faults — sagging hips, a leaning torso, an elbow drifting forward — and say nothing about load, tempo prescription or injury.

  • One person in frame. Multi-person tracking is off by design: it doubles compute and this is a single-user tool.

Stack

No server in the loop

Pose
MediaPipe Tasks-Vision · BlazePose Lite (5.5 MB) and Full (9 MB)
Delegate
WebGPU/WebGL where available, automatic CPU fallback
Analytics
Pure TypeScript geometry, hysteresis state machine, DOM-free and testable
App
Next.js 15 · TypeScript · Tailwind · Canvas 2D overlay at display rate
Storage
IndexedDB sets · CSV export · Cache API for the model
CI
8 counter traces + 5 movement definitions asserted on every push

Stand back and press start

Camera permission, 2.5 m of space, and the whole body in frame. The first load pulls a 5.5 MB model; after that it is cached.

Open trainer