---
id: getting-started/ai-setup
title: AI Setup Prompt
---

<!-- Keep the pinned version below in sync with `docs.version` in
     locales/en/site.json — docs:check asserts it. -->

Copy everything below the line into an agent to set Stift up in a fresh repo.
It distills the `getting-started` and `config` skills into one paste.

---

You are setting up Stift by Secundus, typed build-time-compiled i18n for
TypeScript. Packages live under the `@secundus-studio` scope and are
pre-release: install exactly version 0.4.0, never `latest`.

```bash
pnpm add @secundus-studio/stift-react@0.4.0 @secundus-studio/stift-vite-plugin@0.4.0
```

If the registry needs auth, add the `@secundus-studio` scope line to `.npmrc`
and run with `NPM_TOKEN` set.

Wire the Vite plugin in `vite.config.ts`:

```ts
import { stiftPlugin } from '@secundus-studio/stift-vite-plugin'
export default defineConfig({
  plugins: [stiftPlugin()],
})
```

Write `stift.config.ts`:

```ts
import { defineConfig } from '@secundus-studio/stift-generator'
export default defineConfig({
  locales: { default: 'en', supported: ['en'] },
  namespaces: { dir: 'locales', discovery: 'convention', default: ['common'] },
  messageFormat: 'icu-mf1',
  detection: { order: ['explicit', 'persisted', 'navigator'], fallback: 'en' },
  loadingStrategy: 'critical-then-full-background',
})
```

Start with one locale and one namespace. Add `params.context`, `units`, and
`security.tier` only when the feature calls for them. The default locale is
the schema — it owns every namespace's key set, and new keys propagate to
every other locale automatically.

Create `locales/en/common.json` with one key:

```json
{ "greeting": "Hello, {name}!" }
```

Create the runtime in `src/stift.ts` — everything declarative arrives via the
generated `virtual:stift/runtime` module; this file supplies only what can't
be serialized:

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

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

Boot before rendering in `src/main.tsx`:

```tsx
import { stift, boot } from './stift'

await boot()
render(
  <StiftProvider stift={stift}>
    <Suspense fallback={<FullPageLoader />}><App /></Suspense>
  </StiftProvider>,
)
```

Use it in a component:

```tsx
const { t } = useTranslation('common')
t('greeting', { name: user.name })
```

Verify: `pnpm dev`, the greeting renders from `locales/en/common.json`.

When you need more than this page, load the skill that owns the topic
(`pnpm exec intent load <package>#<skill>`): `stift-vite-plugin#build` for
plugin options, `stift-core#core` for boot and detection,
`stift-generator#config` for the config schema,
`stift-generator#authoring-translations` for writing keys,
`stift-react#react` and `stift-react#values` for hooks and formatting.
The full routing layer is at https://stift.secundus.studio/llms.txt.
The canonical reference app is `examples/tanstack-spa` in the Stift repo.
