eskiuv0.14.1
Case study

Digital identity: an ISO/IEC 39794-5 core in Eskiu

A digital identity company builds and checks the ISO/IEC 39794-5 face record of every capture with one Eskiu core. The same source runs as WebAssembly in its browser SDK and compiles to native libraries with a C ABI for Android and iOS. About 2,500 lines of Eskiu replace logic that each platform would otherwise implement on its own.

The setup

The company makes a web SDK for biometric capture during customer onboarding: a face capture with a liveness check, and the capture of official identity documents and passports. The SDK runs in the user's browser. Images and measurements stay on the device; nothing is sent to a server for processing.

Its output follows ISO/IEC 39794-5, the standard for exchanging face image data. Producing it takes more than saving a photo: the SDK builds the record and its JSON and XML forms, encodes it in ASN.1 and wraps it in a CBEFF block, measures the image's quality and lighting, extracts the face geometry and eye openness from the landmarks, checks the result against configurable profiles, and writes a validation report. All of this was TypeScript, and the native SDKs for Android and iOS would have needed it again in Kotlin and Swift.

Why Eskiu fit

What moved into Eskiu

AreaIn the core
RecordThe public record and its JSON and XML serialization
EncodingsThe ASN.1 TLV writer and the CBEFF block
Image analysisQuality and lighting, computed over the RGBA pixels
FaceGeometry, eye openness and detection confidence
PolicyProfiles, compliance rules and validation reports

The core is about 2,500 lines of Eskiu in 18 files, split by responsibility. TypeScript keeps the public API and its types and becomes an adapter for what belongs to the browser: the camera, Canvas and pixel reads, clocks, the platform's XML parser, Web Crypto, caching and workers. The quality worker loads the same core and the same profiles as the main thread. The WebAssembly module is embedded in a hashed JavaScript chunk, so integrators deploy the SDK exactly as before.

How it was checked

The migration kept the existing behavior where it was right and the existing bytes where they were defined: records match the golden samples of the previous encoder, and the image measurements match the previous TypeScript implementation on deterministic pixel fixtures. 210 tests cover the record, the encodings, the worker, the final capture checks and the eye measurements, another 81 load every bundle the SDK ships, and the native build is exercised through its C ABI with no browser involved. Reformatting the Eskiu sources with eskiuc fmt leaves the compiled object identical byte for byte, which the team uses to keep style changes from hiding behavior changes.

The same sources cross-compile to ARM64 objects for Android and iOS. Linking them into the native apps is the next step of the integration.

The numbers

ImageOperationMedian95th percentile
640×800Quality3.07 ms3.34 ms
640×800Lighting2.45 ms2.46 ms
1920×2400Quality27.15 ms27.29 ms
1920×2400Lighting22.19 ms22.72 ms

Starting the WebAssembly module takes 2 ms, and the memory it keeps reserved after a full analysis went from 52.9 MiB to 23.1 MiB, because the lighting pass no longer stores a double per pixel and recomputes it instead. These are synthetic measurements on an Apple Silicon machine under Node, including copying the pixels in and reading the result out; measurements on entry-level phones are still to come.

Identity checks are a domain where a record has to be the same wherever it is produced. With the logic written once in Eskiu, the browser and the native apps share it instead of keeping three implementations in step.

Start in a minute.

Install the compiler with one command, or run a program in the browser first.