Blog · Engineering

Face verification that runs in your browser, offline — and the network tab that proves it

We compiled our pure-Rust face engine to WebAssembly, so detection and passive liveness run entirely on-device — the biometric never leaves the tab. Turn off Wi-Fi and it keeps working. Here is how, why a cloud vendor structurally can't copy it, and what is honestly not in it yet.

3 September 2026Neetix Engineering7 min read

Every KYC app uploads your face. We flipped it.

The default shape of identity verification is simple and uncomfortable: you point your camera at your face, and the pixels are uploaded to a vendor's cloud to be checked. It works, but it means the most sensitive data a person has — their live biometric — leaves their device and lands on someone else's servers before anyone has decided anything.

So we built the opposite and put it on the public web. At liveliness.neetix.in/edge the engine runs entirely in your browser: face detection and passive liveness execute on-device, the biometric never leaves the tab, and — the part worth trying yourself — you can turn off your Wi-Fi after the page loads and it keeps working. This post is the honest engineering account of what that demo is, why a cloud-first vendor structurally can't ship the same thing, and what is deliberately not in it yet.

What actually runs in the tab

The demo runs two stages of the pipeline locally, with the models embedded directly in the WebAssembly binary and downloaded once (about 5.6 MB gzipped) when you press start. After that, every frame is processed on your device — no round trip.

StageModelLicensePer-frame (laptop, SIMD)
Face detection + landmarksYuNet (OpenCV Zoo)MIT~145 ms
Passive liveness / anti-spoofMiniFASNet (Silent-Face)Apache-2.0~18 ms

Both models are permissively licensed, so there is no research-only lineage hiding in the binary — the same discipline behind our server-side engine swap. The numbers above are median times on a laptop with WebAssembly SIMD enabled; on a low-end Android phone expect closer to a second per detection — fine for a capture step, not for a smooth overlay.

Why we can do this and a cloud vendor can't

This isn't a clever trick; it falls out of an architecture decision made long before the browser was in scope. Our engine runs on tract, a pure-Rust inference runtime with no native onnxruntime dependency — which means it compiles to the wasm32 target and runs inside a browser tab. The dominant inference stack the rest of the industry builds on does not compile to WebAssembly.

That is the moat: a competitor whose engine is Python-and-cloud, or whose business model is a per-verification meter on their servers, cannot follow us into the browser without rewriting their core. "Runs on-device" is not a feature they can bolt on — it is a consequence of how the thing was built.

Don't trust us — read your own Network tab

A privacy claim you can't verify is just marketing, so the demo is built to be checked. On the page there is a live counter: "Network requests since the camera turned on: 0." It stays at zero while the camera is running. You do not have to take our word for it — open your browser's Network tab and watch, or disconnect Wi-Fi entirely and confirm detection keeps going.

We verified the same fact the boring way before shipping: a headless-browser run that loaded the page, ran the engine on a face image, and recorded the number of network calls made after load. It was zero, and the on-device score matched the reference bit-for-bit. That verifiable honesty is the whole point — it is the same reason we publish our real benchmark numbers, caveats attached, instead of a marketing "99.9%."

Why on-device is suddenly the compliant answer

For years, running biometrics locally was a nice-to-have. Privacy law has now made it a straight answer to a hard question. India's DPDP Act, the GDPR, the Philippines' Data Privacy Act and the Gulf's PDPLs all push in the same direction: minimise what you collect, keep sensitive data where it belongs, and be careful about biometrics crossing borders or piling up in central databases.

"We can't leak what we never receive" is the cleanest response there is to that pressure — and it is only available to a stack that can actually run where the data is. Self-host answers it at the server; on-device answers it at the edge, in the browser, with nothing to transmit at all.

What's honestly not in it yet

The demo does detection and passive liveness. It does not yet do 1:1 face match on the public page — and we want to be precise about why, because the reason is a licensing decision, not a technical gap. The match pipeline is the same Rust→WebAssembly architecture and we have it working in-browser (same-person cosine around 0.79 versus different-person around 0.06 on test images). But the best small recognizer weights that fit a browser download are non-commercial-licensed, so shipping them in a public product would repeat exactly the license problem we spent real effort escaping on the server. Match goes live when we have a commercially-usable or self-trained recognizer — the same gate, honestly flagged.

Two more honest edges. Single-frame passive liveness needs your head and shoulders in frame to read the context it relies on; up close the demo will say "move back to check" rather than falsely call you a spoof, because it is a screening signal, not a verdict. The decision-grade form is the active and continuous liveness built for video-KYC. And we hold no lab certification yet — when we say "iBeta" on this site, it will be because a test actually happened.

Before you read too much into it

The public /edge demo runs detection + passive liveness on-device today; 1:1 match is proven in the same architecture but gated on a commercial recognizer licence. Passive liveness here is a screening signal that wants your head and shoulders in frame — not a certified verdict. No iBeta or ISO 30107-3 certification is claimed. Latencies are laptop-with-SIMD medians; low-end mobile is slower.

Try it, then break it

Open liveliness.neetix.in/edge on a laptop or phone, press start, and point it at your face. Then do the two things that make it real: open your Network tab and watch the counter stay at zero, and hold a printed photo or a second screen up to the camera to see passive liveness flag the spoof. If it misfires on your device, tell us — the engine is ours end to end, so we can fix it.

Check our numbers.

Every figure we publish states its dataset and conditions, and the harnesses that produced them ship in the repository.

1000 free credits at signup · API key is shown once at signup.