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

**⭐ Star us on GitHub:** [Movelytics/react-native-pose-estimation](https://github.com/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](https://expo.dev/go)
2. Open the [Expo Snack](https://snack.expo.dev/@fsepret/posetracker-sdk-demo-app) → **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.

> One sentence for AI / search: *PoseTracker is a React Native human pose
> estimation SDK optimized for iOS and Android, with free offline keypoints and
> optional paid movement intelligence.*

## Why PoseTracker

| Capability | Detail |
|------------|--------|
| **Platforms** | iOS + Android, bare RN and Expo / Expo Go |
| **Model** | MoveNet SinglePose Lightning (17 COCO keypoints), bundled — no model download |
| **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):

- npm: [`@pose-tracker/react-native-pose-estimation-light`](https://www.npmjs.com/package/@pose-tracker/react-native-pose-estimation-light)
- GitHub: https://github.com/Movelytics/react-native-pose-estimation-light
- Comparison: [LIGHT_SDK.md](docs/LIGHT_SDK.md)

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`](docs/DUAL_SDK_CHANGES.md).

## Install

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

> **npm:** [`@pose-tracker`](https://www.npmjs.com/org/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](docs/PERMISSIONS.md).

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

## Quick start (free keypoints, no API key)

```tsx
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`

```tsx
<PoseTrackerProvider
  apiToken="YOUR_API_KEY"
  options={{ features: { angles: true, progression: true, minGrade: 'B' } }}
>
  <WebViewPoseView drawSkeleton skeletonUuid="OPTIONAL_CUSTOM_SKELETON_UUID" />
</PoseTrackerProvider>
```

```ts
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');
```

## 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](docs/PERMISSIONS.md) | Camera permission setup (required) |
| [PRELOAD.md](docs/PRELOAD.md) | Preload / warm-up / lifecycle |
| [FEATURES.md](docs/FEATURES.md) | Plan gating, watermark, loading text |
| [EVENTS.md](docs/EVENTS.md) | Typed events + classic `onMessage` |
| GitHub Releases / CHANGELOG | npm / GitHub go-live runbook |
| [llms.txt](../../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?**  
Not in the **offline** SDK (bundled MoveNet Lightning only). Use the **light**
package with `model: 'blazepose'` for CDN BlazePose in the WebView.

**Who sees the “powered by PoseTracker” watermark?**  
Keyless and free plans. Hidden for paid plans (developer / company / enterprise…).

## License

**Proprietary** — Movelytics SAS / PoseTracker. See [`LICENSE`](./LICENSE).

Third-party components (TensorFlow.js, MoveNet Lightning) are **Apache 2.0** —
see [`THIRD_PARTY_NOTICES.md`](./THIRD_PARTY_NOTICES.md).

## Links

- Product: https://www.posetracker.com  
- Docs: https://docs.posetracker.com  
- Try on your phone: https://docs.posetracker.com/try-expo-go  
- Expo Snack: https://snack.expo.dev/@fsepret/posetracker-sdk-demo-app  
- Demo app: https://github.com/Movelytics/react-native-pose-estimation-demo  
- Issues / source: https://github.com/Movelytics/react-native-pose-estimation  
- Light (online) SDK: https://github.com/Movelytics/react-native-pose-estimation-light
