---
id: vanilla/api/create-stift
title: createStift
---

Builds the headless instance. Everything declarative — locales, namespaces, detection order, persisted state — arrives via the generated runtime; the options below supply only what can't be serialized.

```ts
createStift(options): Stift
createStiftApp(options): Promise<{ stift, boot }>
```

## Options

### `...runtime`

- Type: spread of `createStiftRuntime()` (generated config + catalog + source).
- Required. The normalized config, always first.

### `persister`

- Type: `PersisterAdapter` — offline pack store (OPFS/IndexedDB).
- Optional, but offline packs need it. `createStiftApp` also accepts a factory (`() => PersisterAdapter | Promise<PersisterAdapter>`), resolved once — use `createBestEffortPersister` unless you have a reason not to.

### `state`

- Type: `{ prefix?: string; storage?: 'webStorage' | 'cookie' | 'none' }`
- Optional — `default: { prefix: '__stift_', storage: 'webStorage' }`. Persisted user state (locale + param/unit overrides), read synchronously at construction so there is no flash. Normally set in `stift.config.ts`, not here.

### `detectors`

- Type: `{ custom: Detector[] }`
- Optional. Reserved runtime-slot detectors, registered here rather than in config.

### `hooks`

- Type: `StiftRuntimeHooks`, including `onUpdateAvailable` and `onError`.
- Optional. Lifecycle hooks — the missing-key reporter and the update signal live here.

### Loose options

Config overrides applied per-instance before normalization. Prefer `stift.config.ts`; reach for these in tests and SSR harnesses that need a shaped instance.

## `createStiftApp` and `boot`

Same options as `createStift`. `boot({ locale?, critical? })` runs `detectLocale → setLocale → initialize` (initialize unawaited, so first paint stays off the network) and returns the active locale.

`stift.config` is the frozen effective config — `security.staticKey` is never included.

## Examples

```ts
import { createStiftApp } from '@secundus-studio/stift-core'
import { createStiftRuntime } from 'virtual:stift/runtime'
import { createBestEffortPersister } from '@secundus-studio/stift-persisters'

export const { stift, boot } = await createStiftApp({
  ...createStiftRuntime(),
  persister: createBestEffortPersister,
})
```

## Next

- Instance methods → [Stift instance](./stift.md)
- Boot loop and detection order → [Setup & Boot](../setup.md)
- Persisters → [Offline & Persistence](../../runtime/offline-persistence.md)
