# WebAssembly in Web SDK 2.0

This guide is specific to Web SDK 2.0. If you are still using 1.x, you can find documentation [here](https://developer.incode.com/docs/web-sdk-reference). Contact your Incode Representative for upgrade information and check if you are a candidate for this upgrade.

## 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. |
| `videoSelfie`     | `<incode-video-selfie>`, `createVideoSelfieRecordingManager` | ❌ opt-in only                  | Face detection tuned for the video-selfie flow.                             |
| `videoSelfieId`   | `<incode-video-selfie>`, `createVideoSelfieRecordingManager` | ❌ opt-in only                  | Document detection tuned for the video-selfie flow.                         |

`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](https://developer.incode.com/docs/web-sdk-2-on-device-face-capture) for the full walkthrough.

`videoSelfie` and `videoSelfieId` are also opt-in, warmed up via `warmupVideoSelfieWasm` (`@incodetech/core/video-selfie`) rather than the `pipelines` array on `setup({ wasm })`.

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](https://developer.incode.com/docs/web-sdk-2-wasm#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

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

```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                                      |
| `showLogs`        | `boolean` | ❌      | Enable the WASM module's verbose debug logging. Default `false` — the SDK forces WASM into production (quiet) mode unless you opt in. Set to `true` only when debugging WASM issues locally. Do not ship `true` in production. |

`WasmPipeline` is `'selfie' | 'idCapture' | 'onDeviceSelfie' | 'videoSelfie' | 'videoSelfieId'`. Add `'onDeviceSelfie'` only when you've also enabled `onDeviceFaceResultsSubmissionEnabled` on the relevant Selfie or Authentication config; add `'videoSelfie'` / `'videoSelfieId'` only when your flow includes the video-selfie module.

## 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](https://developer.incode.com/docs/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:

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

### Server Configuration

Ensure your server serves WASM files with correct headers:

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