CheckMate gives you an on-device glance at your motor and eye signals after drinking. Calibrate while you're sober — then check later and read your own body.
Free · No account · v1.0
One TypeScript codebase, compiled ahead of time and rendered as native UIs over a high-throughput camera pipeline.
The entire app is written in TypeScript on React Native 0.86 and React 19. There is no WebView anywhere — every screen is native Fabric UI, hand-laid-out to match a design system shared with the backend logic.
The JavaScript bundle runs on the Hermes engine, compiled ahead of time at build time, while a small amount of low-level plumbing (camera permissions, native integration) is in Kotlin. The New Architecture is on — which is what makes frame-by-frame camera processing practical.
The camera never stops: every frame is analyzed live, on the device.
Instead of snapshots, react-native-vision-camera streams frames through native frame processors. Each frame is handed to Google MLKit face detection, which extracts face geometry and landmarks — the raw material for every signal below.
Overlays like the detection ring and the orbiting focal point are driven from the same analysis loop, so guidance and measurement stay in sync to the frame.
A pure-JS model turns raw landmarks into a readable readout.
The analysis layer measures motor steadiness (how still you hold your head inside the ring), pupil response (how accurately your eyes track the moving focal point — a smooth-pursuit task), and blink timing and pattern across the session.
You calibrate once while sober; each signal is then compared against that personal baseline and blended into an overall indicator. The scoring functions are pure and unit-tested with Jest.
Every session records to a single file that plays back instantly.
VisionCamera's built-in video output records the session through the CameraX stack to an on-device file. Playback is handled by react-native-video on the Media3 player — aligned to Media3 1.9 via a targeted patch that resolves a dependency clash in the native build.
Because the capture and playback paths share one pipeline, results appear beside the replay the moment a check finishes.