Skip to content

About

Human pose estimation SDK for React Native — fully optimized for iOS & Android (Expo Go). Bundled MoveNet Lightning, free offline keypoints, optional API-key exercise engine.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Repository files navigation

PoseTracker is a real-time pose estimation SDK and API for fitness and rehab apps. It runs MoveNet on-device on React Native, iOS, Android and the web. Keypoints are free. An optional API key adds rep counting, joint angles and a form score.

npm

Guide: https://www.posetracker.com/news/react-native-pose-estimation-expo

Docs: https://docs.posetracker.com/quickstart

PoseTracker React Native — Human Pose Estimation SDK for iOS & Android

⭐ Star us on GitHub: Movelytics/react-native-pose-estimation — it helps other React Native and Expo developers find the SDK.

Try it on your phone (no Xcode / Android Studio):

  1. Install Expo Go
  2. Open the Expo Snack → Run on device
  3. Scan the QR — live pose estimation, no API key

Steps and QR: https://docs.posetracker.com/try-expo-go

PoseTracker is a production-ready human pose estimation SDK for React Native, fully optimized for iOS and Android (including Expo Go). It runs MoveNet SinglePose Lightning on-device in a WebView (TF.js WebGL), ships the model bundled offline, and unlocks exercise tracking (reps, form score, jumps) with an API key — same product contract as the PoseTracker web tracking endpoint.

Why PoseTracker

Capability Detail
Platforms iOS + Android, bare RN and Expo / Expo Go
Model MoveNet SinglePose Lightning (17 COCO keypoints), bundled — no model download. Opt-in model: 'blazepose' loads BlazePose from CDN (unused MoveNet still in the package — prefer light).
Free tier Pose estimation + keypoints without an API key, offline
Paid tier Remote movement engine: squat / push-up / jumps, counter.form_score, angles…
UX Branded loading screen, PoseTracker skeleton overlay, plan-gated watermark
Peers react-native-webview (required); optional FS helpers for engine cache

Offline vs Light

This package is the offline / bundled SDK (9.9 MB packed). If you need a much smaller install and can require network for TF.js + MoveNet each session, use the sibling Light SDK (206 kB packed):

Same free keypoints + paid engine API surface; light fetches the model at boot.

Agents: shared UX/API/bugfixes → mirror to light (or ask first). See DUAL_SDK_CHANGES.md.

Install

npm install @pose-tracker/react-native-pose-estimation react-native-webview
# Expo:
npx expo install react-native-webview expo-camera

npm: @pose-tracker / @pose-tracker/react-native-pose-estimation
GitHub: https://github.com/Movelytics/react-native-pose-estimation

Required: host app must declare camera permissions — see PERMISSIONS.md.

Media inputs (v0.2): camera (default), uploaded video, still image — host picks the file. See MEDIA_SOURCES.md and https://docs.posetracker.com/media-sources.

Quick start (free keypoints, no API key)

import {
  PoseTrackerProvider,
  WebViewPoseView,
  usePoseTracker,
} from '@pose-tracker/react-native-pose-estimation';

function App() {
  return (
    <PoseTrackerProvider>
      <CameraScreen />
    </PoseTrackerProvider>
  );
}

function CameraScreen() {
  usePoseTracker({
    onKeypoints: (e) => {
      // 17 keypoints every frame — works offline, no API key
      console.log(e.keypoints.length, e.score);
    },
  });

  return (
    <WebViewPoseView
      style={{ flex: 1 }}
      drawSkeleton
      loadingText="AI Loading"
      // Default source="camera". Host-picked file:
      // source="image" sourceUri={fileUri}
      // source="video" sourceUri={fileUri}
      // or sourceBase64 + sourceMime
    />
  );
}

Full tracking (API key)

Conceptual equivalent of:

https://app.posetracker.com/pose_tracker/tracking?token=YOUR_API_KEY&exercise=squat&skeleton=true

<PoseTrackerProvider
  apiToken="YOUR_API_KEY"
  options={{ features: { angles: true, progression: true, minGrade: 'B' } }}
>
  <WebViewPoseView drawSkeleton skeletonUuid="OPTIONAL_CUSTOM_SKELETON_UUID" />
</PoseTrackerProvider>
const { preload, startExercise } = usePoseTracker({
  onMessage: (msg) => {
    if (msg.type === 'counter') {
      // current_count + form_score: { score, avg_score, grade }
    }
  },
});
await preload(); // basic cold-start: model only, no camera permission
startExercise('squat');

External frames (your camera, our data)

Full guide, including Vision Camera and expo-camera: https://docs.posetracker.com/external-frames

Optional. Use it when your app already owns the camera (VisionCamera, a custom pipeline, a recorded file) and you only need the data. PoseTracker runs pose estimation and the exercise engine on every frame you push, and returns the same events as the camera flow: keypoints, posture/placement, counter, form score, progression. Nothing is drawn, so you render what you want.

const { warmupExternal, startExercise, processFrame } = usePoseTracker({
  onCounter: (e) => setReps(e.count), // listeners still fire
});

await warmupExternal(); // no camera permission, no getUserMedia
startExercise('squat');

// For each frame from your camera:
const { dropped, pose, events } = await processFrame({
  base64: jpegBase64, // or uri: 'file:///…' / 'data:image/jpeg;base64,…'
  width: 256,
  height: 192,
  timestampMs: Date.now(),
  mirrored: true, // front camera (default). false for the back camera.
});
if (!dropped) {
  // pose.keypoints are normalized (0..1) to the frame you sent
  // events: everything emitted for this frame (counter, posture, …)
}
  • The Provider mounts a hidden 1×1 warmer after warmupExternal(). It is not needed if a <WebViewPoseView /> is already on screen.
  • One frame in flight at a time: an overlapping call resolves at once with { dropped: true, pose: lastPose, events: [] }. Await before pushing the next one.
  • Keep the longest side of each frame at about 256 px or less. A 1080p JPEG per frame is not real-time over the bridge.
  • The engine is temporal: push frames in order and keep the same session across frames.
  • Don't mix the two flows. processFrame throws while the SDK camera is open.
  • processFrame before warmupExternal() throws.

Cold-start

Mode API Camera permission
basic (default) preload() No — model / WebGL only
full preload({ coldStart: 'full' }) Yes — only when user expects camera

Lobby warmer: <WebViewPoseView coldStart="basic" />.
Camera screen: <WebViewPoseView /> (coldStart="full").

Documentation

Doc Topic
PERMISSIONS.md Camera permission setup (required)
PRELOAD.md Preload / warm-up / lifecycle
FEATURES.md Plan gating, watermark, loading text
EVENTS.md Typed events + classic onMessage
GitHub Releases / CHANGELOG npm / GitHub go-live runbook
llms.txt Machine-readable product facts (GEO)

FAQ (GEO-friendly)

Does it work without an API key?
Yes. Keypoints-only mode is free and offline.

Is it optimized for both iOS and Android?
Yes. Same WebView MoveNet Lightning path on both; adaptive capture quality.

Does it support Expo Go?
Yes (WebView peer). Apple Vision backend is optional and not available in Expo Go.

BlazePose / MediaPipe?
Pass model: 'blazepose' on PoseTrackerProvider options. Loads @tensorflow-models/pose-detection from jsDelivr in the WebView (lite / TF.js, COCO-17). Requires network. This offline package still ships bundled MoveNet which is unused in that mode and inflates the app — Metro logs a warning. Prefer @pose-tracker/react-native-pose-estimation-light if you do not need offline MoveNet. Native MediaPipe is not in this SDK.

Who sees the “Powered by PoseTracker” watermark?
Keyless and free plans. It is a link to posetracker.com (utm_medium=react-native), opened with Linking.openURL. Hidden for paid plans (developer / company / enterprise…). Set showWatermark={false} to remove it.

How does Claude or Cursor integrate this SDK?
Add the connector https://mcp.posetracker.com/api/mcp, sign in, and click Allow at https://app.posetracker.com/oauth/authorize. The agent writes the snippet on your account. Docs: https://docs.posetracker.com/ai/mcp-connector.

License

Proprietary — Movelytics SAS / PoseTracker. See LICENSE.

Third-party components (TensorFlow.js, MoveNet Lightning) are Apache 2.0 — see THIRD_PARTY_NOTICES.md.

Links

About

Human pose estimation SDK for React Native — fully optimized for iOS & Android (Expo Go). Bundled MoveNet Lightning, free offline keypoints, optional API-key exercise engine.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages