> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hyperauth.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Local development

> Run a HyperAuth client app, the Vault Worker, and the WASM signer enclave together on your laptop with hot reload, mock OTP delivery, and local D1.

<Info>
  **Prerequisites**

  * Node.js 18 or higher
  * Bun (for compiling WASM artifacts)
  * The `wrangler` CLI if running the Vault Worker locally
</Info>

## Project layout

A typical HyperAuth app has three moving parts:

| Component        | Runtime                                  | Notes                                           |
| ---------------- | ---------------------------------------- | ----------------------------------------------- |
| Your React app   | Vite or your preferred bundler           | Imports `@hyperauth/sdk` and `@hyperauth/react` |
| Stateless signer | `enclave.wasm` inside a Dedicated Worker | One per browser tab                             |
| Stateful vault   | `vault.wasm` inside a SharedWorker       | One per origin                                  |

The signer and vault are loaded by `HyperAuthProvider` from `/enclave.wasm` and `/vault.wasm` by default. You can serve them from your app's `public/` directory in development, or from a CDN such as Cloudflare R2 in production.

## Compile the WASM artifacts

From the monorepo root:

```bash theme={null}
bun run compile:wasm
```

This emits `core/enclave/dist/enclave.wasm` and `core/vault/dist/vault.wasm`. Copy them into your app's `public/` directory before starting the dev server:

```bash theme={null}
cp core/enclave/dist/enclave.wasm apps/my-app/public/
cp core/vault/dist/vault.wasm apps/my-app/public/
```

<Tip>
  Wire `predev` and `prebuild` hooks in your app's `package.json` to copy the binaries automatically each time you run `vite` or build for production.
</Tip>

## Start the dev server

Run your app's dev script:

```bash theme={null}
npm run dev
```

The default Vite URL is `http://localhost:5173`. The SDK's defaults (`/enclave.wasm`, `/vault.wasm`, `/api/bundler`, `/api/indexer`) resolve against the same origin, so a proxy to the Vault Worker on port `8787` works without any additional configuration.

## Run the Vault Worker locally

If your client needs the Vault Worker's HTTP API (e.g. for `/api/sessions` or `/api/dids`), run it under wrangler:

```bash theme={null}
cd apps/vault
wrangler dev
```

The dev server starts on `http://localhost:8787`. Add the secrets your local Worker requires to `apps/vault/.dev.vars`:

```sh apps/vault/.dev.vars theme={null}
PIMLICO_API_KEY=your_key
TWILIO_ACCOUNT_SID=your_sid
RESEND_API_KEY=your_key
ATTESTATION_SIGNING_KEY=your_key
```

<Warning>
  Never commit `.dev.vars`. It's gitignored by default in the starter Worker template.
</Warning>

## Validate documentation links

If you're editing this docs site, the Mintlify CLI can check for broken links:

```bash theme={null}
mint broken-links
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Worker fails to load enclave.wasm">
    The most common cause is the WASM file is missing from `public/`. Run `bun run compile:wasm` and copy the artifacts as shown above. If the file is present, check that your dev server is serving it with `Content-Type: application/wasm` — Vite handles this automatically; other bundlers may need a plugin.
  </Accordion>

  <Accordion title="SharedWorker not available">
    SharedWorker is not supported in some browsers (notably Safari on iOS prior to iOS 16). The SDK detects this and surfaces an `error` status via the provider. Test in Chrome or Firefox first to rule out platform-specific behavior.
  </Accordion>

  <Accordion title="Vault locked after page reload">
    By default the vault auto-locks after 5 minutes of inactivity, and a page reload always loses in-memory state. Persist the encrypted database via `client.setAutoLockCallback` or call `client.exportVault({ password })` and store the result yourself. See [Vault Management](/guides/vault-management) for the full workflow.
  </Accordion>
</AccordionGroup>
