# WASM Configuration

<WebSDK2 />

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. 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](doc:web-sdk-2-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](#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:

```typescript
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`:

```typescript
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

| 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

`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](doc:web-sdk-2-e2ee) 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:**

```nginx
types {
  application/wasm wasm;
}
```

**Apache:**

```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

| 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](doc:web-sdk-2-module-selfie-1): Selfie capture documentation
* [Troubleshooting](doc:web-sdk-2-troubleshooting): Common issues
