On-device quickstart

  1. 1

    Install

    bash
    git clone https://github.com/neetixai/liveliness-sdks
    npm i ./liveliness-sdks/packages/edge

    npm i @neetix/edge is the intended install; the registry publish is pending.

    The wasm binary is built, not committed

    The package needs wasm/neetix_edge.js and wasm/neetix_edge_bg.wasm (~17 MB), which are produced by wasm-pack in the engine repo and are gitignored here. A checkout without them installs cleanly and then fails to load at runtime. The package's prepublishOnly guard refuses to publish a tarball that is missing them, or whose .wasm is under 1 MB — that size check catches the .d.ts placeholder being packed instead of the real binary.

  2. 2

    Load the engine

    ts
    import { NeetixEdge } from "@neetix/edge";
    
    const edge = await NeetixEdge.load();   // fetches + initialises the wasm, once

    This is the only network activity in the whole flow, and it is cacheable. Do it behind a loading state — it is a multi-megabyte download on first visit.

  3. 3

    Detect and score a frame

    ts
    const faces = edge.detect(videoEl);     // ImageData | Canvas | Video
    
    if (faces[0]) {
      const live = edge.liveness(videoEl, faces[0]);
      console.log(faces[0].box, live.live, live.score);
    }

    detect and liveness accept an ImageData, an HTMLCanvasElement or an HTMLVideoElement — including a live getUserMedia stream. Inputs are normalised to ImageData internally through an offscreen canvas.

  4. 4

    Drive it from a live camera

    ts
    const videoEl = document.querySelector("video")!;
    videoEl.srcObject = await navigator.mediaDevices.getUserMedia({ video: true });
    await videoEl.play();
    
    const edge = await NeetixEdge.load();
    
    function tick() {
      const faces = edge.detect(videoEl);
      if (faces[0]) {
        const live = edge.liveness(videoEl, faces[0]);
        setHint(live.live ? "Hold still" : "Move into better light");
      } else {
        setHint("Center your face");
      }
      requestAnimationFrame(tick);
    }
    tick();

    Prefer this shape — per-frame hints during capture — over scoring a single still. It is what stops a user submitting a frame that was always going to be rejected.

Prove it is offline

The claim is checkable, and showing it is more convincing than saying it:

  1. Load the page and wait for NeetixEdge.load() to resolve.
  2. Open DevTools ▸ Network and clear it, or turn off Wi-Fi.
  3. Keep using the camera. Detection and liveness keep working with no requests.

Next