WASM Configuration

📘

This guide is specific to Web SDK 2.0. If you are still using 1.x, you can find documentation here. We strongly recommend upgrading - contact your Incode Representative for upgrade information.

WebAssembly (WASM) powers the SDK's on-device ML pipelines — face detection and liveness for the Selfie module, document detection and quality scoring for the ID Capture module.

When WASM is Required

The SDK ships the following ML pipelines, all delivered as WebAssembly:

PipelineUsed byDefault warmup?What it does
selfie<incode-selfie>, <incode-authentication> (via createAuthenticationManager), createSelfieManager✅ when pipelines omittedFace detection, positioning feedback, liveness analysis.
idCapture<incode-id>, createIdCaptureManager✅ when pipelines omittedDocument detection plus blur / glare / barcode quality checks during capture.
onDeviceSelfieSelfie / Authentication when onDeviceFaceResultsSubmissionEnabled: true❌ opt-in onlyOn-device face-results pipeline. Computes the face analysis client-side; the SDK submits the results to the server only.

onDeviceSelfie is opt-in — it is not in the default pipelines set. Enabling it has prerequisites beyond just the WASM pipeline (E2EE-provisioned apiURL, the onDeviceFaceResultsSubmissionEnabled config flag, and an API-key transmission choice); see On-Device Face Capture for the full walkthrough.

WASM is not needed for phone verification, email verification, consent, redirect-to-mobile, or any flow that doesn't include the selfie or ID-capture modules — unless you enable End-to-end encryption, which routes all SDK traffic through the WASM transport.

Configuration

The simplest integration is the wasm option on setup(). It accepts a WasmConfig object, the literal false, or can be omitted entirely:

import { setup } from '@incodetech/core';
import { initializeSession } from '@incodetech/core/session';

// 1. Default: omit the option — the SDK does NOT preload WASM.
//    It loads lazily on first selfie or ID capture.
await setup({ apiURL: 'https://demo-api.incodesmile.com' });
await initializeSession({ token: 'your-session-token' });

// 2. Preload using Incode's CDN defaults (recommended for most apps).
//    Paths and model files come from the CDN; you only choose pipelines.
await setup({
  apiURL: 'https://demo-api.incodesmile.com',
  wasm: { pipelines: ['selfie'] }, // or ['selfie', 'idCapture']
});
await initializeSession({ token: 'your-session-token' });

// 3. Self-hosted: override paths individually. Anything you omit
//    falls back to the CDN default.
await setup({
  apiURL: 'https://demo-api.incodesmile.com',
  wasm: {
    wasmPath: '/wasm/webLib.wasm',
    glueCodePath: '/wasm/webLib.js',
    modelsBasePath: '/wasm/models',
  },
});
await initializeSession({ token: 'your-session-token' });

// 4. Explicitly disable WASM warmup (e.g. when this page only runs
//    phone or email verification, and you want to skip the bundle cost).
await setup({ apiURL: 'https://demo-api.incodesmile.com', wasm: false });
await initializeSession({ token: 'your-session-token' });

Each snippet pairs setup({ apiURL, wasm? }) (which provisions the HTTP client and optionally warms up WASM) with initializeSession({ token }) (which activates the session). The one-shot form setup({ apiURL, token }) is still supported and delegates to initializeSession internally — splitting them out lets you start setup before the session token exists, e.g. to begin WASM warmup while createSession is still in flight.

Advanced: warmupWasm() directly

For headless integrations or callers that want to pre-warm WASM before setup() runs (or with stricter typing), import the underlying helper from @incodetech/core/wasm:

import { warmupWasm } from '@incodetech/core/wasm';

await warmupWasm({
  wasmPath: '/wasm/webLib.wasm',
  wasmSimdPath: '/wasm/webLibSimd.wasm', // optional SIMD variant
  glueCodePath: '/wasm/webLib.js',
  modelsBasePath: '/wasm/models', // default: inferred from wasmPath
  pipelines: ['selfie', 'idCapture'], // default: both pipelines
});

WarmupConfig (the type that warmupWasm accepts) requires wasmPath and glueCodePath. WasmConfig (the type setup({ wasm }) accepts) makes those optional and fills missing fields from the Incode CDN.

WarmupConfig properties

PropertyTypeRequiredDescription
wasmPathstringPath to the .wasm binary
glueCodePathstringPath to the JS glue code
wasmSimdPathstringSIMD-optimized .wasm (falls back to wasmPath)
glueCodeSimdPathstringPath to the SIMD-optimized glue code (paired with wasmSimdPath). Defaults to a sibling .js derived from wasmSimdPath.
useSimdbooleanUse SIMD when available (default: true)
pipelinesWasmPipeline[]Pipelines to preload (default: ['selfie', 'idCapture'])
modelsBasePathstringBase path for model files (default: derived from wasmPath)
pipelineModelsobjectOverride model file names per pipeline

WasmPipeline is 'selfie' | 'idCapture' | 'onDeviceSelfie'. Add 'onDeviceSelfie' only when you've also enabled onDeviceFaceResultsSubmissionEnabled on the relevant Selfie or Authentication config.

End-to-end encryption

setup({ encryption: true }) opts the SDK into end-to-end-encrypted transport for every request. The encrypted transport runs over the WASM binary channel — the legacy plain fetch / XHR transport does not support E2EE.

E2EE is a one-flag enable but has provisioning prerequisites (dedicated apiURL, MGF1 scheme, and an API-key transmission choice) that can't be guessed. See End-to-End Encryption for the full walkthrough, including the /0 vs customHeaders: { 'x-api-key': ... } choice and failure-mode troubleshooting.

Hosting WASM Files

Copy WASM files to your public assets directory:

public/
  wasm/
    webLib.wasm
    webLibSimd.wasm
    webLib.js
    models/
      *.ortmodelv2

Server Configuration

Ensure your server serves WASM files with correct headers:

Content-Type: application/wasm

Nginx:

types {
  application/wasm wasm;
}

Apache:

AddType application/wasm .wasm

SIMD Support

The SDK automatically uses SIMD-optimized WASM when the browser supports it, falling back to standard WASM otherwise. Provide both files for best compatibility.

Lazy Loading

If you don't pass a wasm option to setup(), WASM stays unloaded until the first <incode-selfie> or <incode-id> (or their headless createSelfieManager / createIdCaptureManager counterparts) actually needs it. This keeps the initial bundle small for pages that only run phone, email, or consent flows. For latency-sensitive selfie/ID flows, prefer wasm: { pipelines: [...] } so warmup runs while the user is on earlier steps.

Troubleshooting

IssueSolution
WASM not loadingCheck file paths and server MIME types
404 errorsVerify files are in your public directory
Face detection not workingEnsure models are in the correct path

See Also