---
source: https://cli.eloqnt.dev/docs/configuration
docs_index: https://cli.eloqnt.dev/llms.txt
---

# Configuration

Configuration for eloqnt/cli is defined locally in your project repository.

All configuration lives in `.eloqnt/config.ts` at your project root:

```ts title=".eloqnt/config.ts"
import {defineConfig} from '@eloqnt/cli';

export default defineConfig({
  srcPath: './src',
  messages: {
    path: './messages',
    locales: 'infer',
    sourceLocale: 'en',
    format: 'json'
  }
});
```

## `srcPath`

`string | Array<string>` (optional)

Relative path(s) to the source code that uses your messages (`next-intl` only).

```ts title=".eloqnt/config.ts"
import {defineConfig} from '@eloqnt/cli';

export default defineConfig({
  srcPath: './src'
  // ...
});
```

When set, the CLI analyzes your source code: AST-level lint rules like `orphan-message` and `undefined-key` become available, and translation runs automatically pick up context from the call sites of your messages.

In a monorepo, you can pass an array of relative source roots, including sibling or installed packages (see the [`next-intl` docs](https://next-intl.dev/docs/usage/extraction#monorepos-external-packages)).

## `messages`

`object`

Describes your message catalogs: where they live and how they're stored.

```ts title=".eloqnt/config.ts"
import {defineConfig} from '@eloqnt/cli';

export default defineConfig({
  messages: {
    path: './messages',
    locales: 'infer',
    sourceLocale: 'en',
    format: 'json'
  }
  // ...
});
```

### `messages.path`

`MessagesPathEntry | Array<MessagesPathEntry>`

The relative path to the directory containing your messages, with one file per locale.

For example:

```tsx
path: './messages';
```

… corresponds to:

- `./messages/en.json`
- `./messages/es.json`
- etc.

You can also pass an array of paths when your app messages are sourced from multiple places:

```tsx
path: ['./messages', '../ui/messages'];
```

Note that all messages share the same root namespace in this case (contrary to when using a `{namespace}` placeholder—see below).

---

For more advanced setups, there are three placeholders available:

1. `{locale}`: Resolves to a given locale (e.g. `'en'`)
2. `{namespace}`: Splits messages per namespace (the first part of a message ID)
3. `{code}`: Custom mapping for locales to files via [`messages.codes`](#messages-codes) (defaults to `{locale}`)

For example:

```ts title=".eloqnt/config.ts"
import {defineConfig} from '@eloqnt/cli';

export default defineConfig({
  messages: {
    path: './locales/{locale}/{namespace}',
    locales: 'infer',
    sourceLocale: 'en',
    format: 'json'
  }
});
```

… will match files like:

- `./locales/en/auth.json`
- `./locales/es/auth.json`
- etc.

Formats that keep all locales in one shared file can point `path` at the file itself (without an extension or placeholder)—see [custom formats](https://cli.eloqnt.dev/docs/formats/custom).

Additionally, if your source and target messages use a different path, you can split `path` into an object with separate properties for each:

```ts title=".eloqnt/config.ts"
import {defineConfig} from '@eloqnt/cli';

export default defineConfig({
  messages: {
    path: {
      source: './i18n/Messages',
      targets: './i18n/Messages_{locale}'
    }
    // ...
  }
});
```

The `source` path holds the source locale's file and uses no locale placeholder, while `targets` must contain `{locale}` or `{code}`.

### `messages.locales`

`'infer' | Array<string>`

The locales to translate between.

Pass `'infer'` to detect your target locales from the files in the messages directory. If you prefer to be explicit, e.g. when `messages.path` contains non-messages, you can list the locales with an explicit array.

### `messages.sourceLocale`

`string`

The primary locale that serves as the source for translations.

### `messages.format`

`MessageFormat`

Defines how your messages files are stored, the built-in formats are:

1. `'po'` (recommended)
2. `'json'`

For advanced cases and libraries other than `next-intl`, see the docs on [custom formats](https://cli.eloqnt.dev/docs/formats/custom).

### `messages.codes`

`Record<string, string>` (optional)

If your files don't match your locales, you can add a mapping:

```ts title=".eloqnt/config.ts"
import {defineConfig} from '@eloqnt/cli';

export default defineConfig({
  messages: {
    codes: {
      'de-AT': 'de-rAT',
      'es-419': 'b+es+419'
    }
    // ...
  }
});
```

This establishes the `{code}` placeholder which can then be used in [`messages.path`](#messages-path).

## `lint`

`object` (optional)

Configures how [`eloqnt lint`](https://cli.eloqnt.dev/docs/cli/lint) reports its rules.

### `lint.rules`

`LintRulesConfig` (optional)

Sets the severity of individual rules:

- `'error'`: Fails the run
- `'warn'`: Reports without failing
- `'off'`: Disables the rule entirely

Rules you don't list keep their default severity (see the [rules overview](https://cli.eloqnt.dev/docs/cli/lint#rules)).

```ts title=".eloqnt/config.ts"
import {defineConfig} from '@eloqnt/cli';

export default defineConfig({
  lint: {
    rules: {
      // Completeness is tracked in an external system
      'missing-translation': 'off'
    }
  }
  // ...
});
```

Warnings still fail the run when you pass `--strict` to `eloqnt lint`.

### `lint.overrides`

`Array<LintOverride>` (optional)

Applies rule settings only to matching message keys. Entries apply in order, with the last matching entry winning over [`lint.rules`](#lint-rules) and earlier entries.

```ts title=".eloqnt/config.ts"
import {defineConfig} from '@eloqnt/cli';

export default defineConfig({
  lint: {
    overrides: [
      {
        // Keys under `products.` are constructed dynamically
        keys: 'products.*',
        rules: {'orphan-message': 'off'}
      }
    ]
  }
  // ...
});
```

The `keys` field accepts one or more patterns matched against message keys, where a single `*` matches any sequence of characters.

## `model`

`LanguageModel` (optional)

On the ["Bring your own model"](https://engine.eloqnt.dev/plans) plan, translations run through a model you configure yourself, with any provider the [AI SDK](https://ai-sdk.dev/providers/ai-sdk-providers) supports. All inference then runs through your model, and no messages or source code ever touch our backend.

```ts title=".eloqnt/config.ts"
import {anthropic} from '@ai-sdk/anthropic';
import {defineConfig} from '@eloqnt/cli';

export default defineConfig({
  // Pick any model supported by the AI SDK
  model: anthropic('claude-opus-5')

  // ...
});
```

Note that you may need to set provider environment variables like `ANTHROPIC_API_KEY`.

### Using a coding agent subscription (Claude Code, Codex, …)

If you already subscribe to a coding agent, 3rd-party providers let you use it as your model (examples: [Claude Code](https://ai-sdk.dev/providers/community-providers/claude-code), [Codex](https://ai-sdk.dev/providers/community-providers/codex-cli)). No separate API key needed.

```ts title=".eloqnt/config.ts"
import {claudeCode} from 'ai-sdk-provider-claude-code';
import {defineConfig} from '@eloqnt/cli';

export default defineConfig({
  model: claudeCode('opus')

  // ...
});
```

**Note:** These providers are community-maintained, and whether your subscription allows this kind of use is up to the vendor. That can change at any time, so check that it's in line with the plan you're using.

## `styleguides`

`string` (optional)

Relative path to the directory that holds your [styleguides](https://cli.eloqnt.dev/docs/styleguides) (defaults to `.eloqnt`).

Especially if you want to share styleguides among multiple consumers, it can be handy to centralize them:

```ts title=".eloqnt/config.ts"
import {defineConfig} from '@eloqnt/cli';

export default defineConfig({
  styleguides: '../i18n/styleguides'
  // ...
});
```

---

For an index of every eloqnt/cli documentation page, see [https://cli.eloqnt.dev/llms.txt](https://cli.eloqnt.dev/llms.txt).
