WASM Configuration
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
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:
| Pipeline | Used by | Default warmup? | What it does |
|---|---|---|---|
selfie | <incode-selfie>, <incode-authentication> (via createAuthenticationManager), createSelfieManager | ✅ when pipelines omitted | Face detection, positioning feedback, liveness analysis. |
idCapture | <incode-id>, createIdCaptureManager | ✅ when pipelines omitted | Document detection plus blur / glare / barcode quality checks during capture. |
onDeviceSelfie | Selfie / Authentication when onDeviceFaceResultsSubmissionEnabled: true | ❌ opt-in only | On-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 and is only loaded when a Selfie or Authentication config has onDeviceFaceResultsSubmissionEnabled: true (see Module: Selfie and Module: Authentication).
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
warmupWasm() directlyFor 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
WarmupConfig properties| Property | Type | Required | Description |
|---|---|---|---|
wasmPath | string | ✅ | Path to the .wasm binary |
glueCodePath | string | ✅ | Path to the JS glue code |
wasmSimdPath | string | ❌ | SIMD-optimized .wasm (falls back to wasmPath) |
glueCodeSimdPath | string | ❌ | Path to the SIMD-optimized glue code (paired with wasmSimdPath). Defaults to a sibling .js derived from wasmSimdPath. |
useSimd | boolean | ❌ | Use SIMD when available (default: true) |
pipelines | WasmPipeline[] | ❌ | Pipelines to preload (default: ['selfie', 'idCapture']) |
modelsBasePath | string | ❌ | Base path for model files (default: derived from wasmPath) |
pipelineModels | object | ❌ | Override 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
Setting 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.
Not a self-serve flag — contact your Incode account team first. E2EE has to be provisioned for your account. Once enabled, Incode will give you:
- A dedicated
apiURLto point at — E2EE traffic is served from a different host than the regular API. Pointingencryption: trueat your standardapiURLwill fail the handshake atsetup().- The
mgf1scheme that environment expects ('sha1'by default, or'sha256'for some environments) — pass it viaencryption: { mgf1: 'sha256' }.Both values are dictated by the environment Incode has provisioned for you, not by you. Don't guess — confirm with your account team.
Other constraints:
setup({ wasm: false, encryption: true })throws. Either omitwasm(the SDK provisions the binary transport with CDN defaults automatically) or pass aWasmConfigobject alongsideencryption: true.encryption: truedoes not require a session token. The handshake runs as part ofsetup()itself, before any per-session calls.- Encryption is locked at boot. The first
setup()call decides whether encryption is on, and whichmgf1scheme is used. Subsequentsetup()calls that would change either value throw. Callreset()first if you genuinely need to switch. - If the handshake fails (unreachable
apiURL, environment without E2EE provisioning, mismatchedmgf1, transient network or server error),setup()rejects with a descriptive error. There is no built-in retry — catch and re-call.
// apiURL here is the dedicated E2EE host Incode provisioned for your account
// (not your standard apiURL).
await setup({
apiURL: 'https://<your-incode-e2ee-host>',
encryption: true, // binary transport provisioned automatically; uses default mgf1 ('sha1')
});
// With an explicit mgf1 scheme (use whichever Incode tells you to use):
await setup({
apiURL: 'https://<your-incode-e2ee-host>',
encryption: { mgf1: 'sha256' },
});
// With self-hosted WASM:
await setup({
apiURL: 'https://<your-incode-e2ee-host>',
encryption: true,
wasm: {
wasmPath: '/wasm/webLib.wasm',
glueCodePath: '/wasm/webLib.js',
modelsBasePath: '/wasm/models',
},
});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 .wasmSIMD 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
| Issue | Solution |
|---|---|
| WASM not loading | Check file paths and server MIME types |
| 404 errors | Verify files are in your public directory |
| Face detection not working | Ensure models are in the correct path |
See Also
- Module: Selfie: Selfie capture documentation
- Troubleshooting: Common issues
Updated about 5 hours ago
