---
title: App config & language
description: Select configuration for the user and understand when app-visible changes take effect.
---

[!nav:main](/nav/main.md)

Pass your app's model choice, instructions, agent definitions, and tool declarations in `config` when you call `Croche.open(...)`. Tool handlers and credentials stay outside that config.

## Choose a model

**Your app can choose the model.** Set `model` inside the `config` passed to `Croche.open`,
not as a top-level open option:

```ts
const config = {
  model: 'deepseek/deepseek-v4.1-flash',
  instructions: 'You are a friendly guide. Keep replies brief.',
};
// Use this as the config option in your existing Croche.open call.
```

| Scope | Config field |
| --- | --- |
| Project | `config.model` |
| Project language | `config.languages.<tag>.model` |
| Agent | `config.agents.<agentId>.model` |
| Agent language | `config.agents.<agentId>.languages.<tag>.model` |

For the selected agent and language, later applicable levels override earlier ones in that
order: project → project language → agent → agent language. Omitting `model` at one level
inherits the preceding applicable value. Modes do not declare `model`.

If no applicable level sets `model`, the default is `deepseek/deepseek-v4.1-flash`, with
`openai/gpt-6-luna` fallback only at reasoning `default` or `off`, not `low`, `medium`, or `high`.
See [Models](../models.md) for recommendations, [fallback limits](../models.md#when-model-is-unset),
and the [allowed model IDs](../models.md#allowed-model-ids). Set `config.model` explicitly when
you want a particular model.

## User language and config language are different

| Option | Meaning |
| --- | --- |
| `language` on `Croche.open(...)` | The **user's language**, as a BCP-47 tag such as `ko` or `en-US` |
| `config.defaultLanguage` | The language the **base config is written in**, default `"en"`; not the user's language or a fallback for it |
| `config.languages.<tag>` | A translated config branch for that language tag |

`language` selects the matching translated branch in `config.languages.<tag>`: **the exact tag first, then the primary subtag**. For `ko-KR`, Croche looks for `ko-KR`, then `ko`. If neither matches, the **base config is used as is**, in the language recorded by `config.defaultLanguage`. `config.defaultLanguage` is used only to select the config layer; it does not change the user's language. Croche does not translate the base config for you.

**An English-only config still serves a Korean user.** For example, with `config.defaultLanguage: 'en'`, no matching Korean branch, and `language: 'ko'`, the app uses the unchanged English base config. A Korean user's language does not have to match the language in which you wrote your config.

### When you omit language

The default contract, when your app does not pass `language`, is the device or browser locale on every SDK. Availability differs by SDK:

| SDK environment | Locale source |
| --- | --- |
| Browser | `navigator.language` |
| React Native | Automatic device locale pending 0.5.1; pass `language` explicitly until verified |
| Native Swift | Automatic device locale pending 0.5.1; final native API review pending |
| Native Kotlin | Automatic device locale pending 0.5.1; final native API review pending |

For a Node backend serving multiple people, pass each user's language explicitly rather than treating the server's locale as the user's. With mobile 0.5.0 examples, pass `language` explicitly; automatic mobile device-locale selection is not yet verified.

### The reply language

The model is **not told the value of `language`**. It replies in the language the user writes, unless your instructions say otherwise. The option selects config; it is not a command to make the model reply in that language.

In the English-config/Korean-user example, a user can write in Korean and receive a Korean reply without a Korean config branch, unless the instructions require another reply language.

## Studio config replaces code config

A Studio AI config received through `Croche.open(...)` replaces the app's code config **as a whole**, for both drafts and releases. It does not merge with the code config.

Use `Croche.open(...)` in TypeScript or React Native for the hackathon. Native [Swift](../sdks/ios.md) and [Kotlin](../sdks/android.md) setup is pending API review. The separate `CrocheRuntime.create(...)` API never uses Studio config.

## Changes apply on the next open

A Studio config takes effect on the **next open after a sync**, never in an already-open session. Saving a draft or publishing a release does not immediately change a running session.

Drafts reach only installations using a debug key (`debugKey`). **Every debug key follows drafts by default; there is no toggle.** Your development run can therefore use the Studio draft instead of the code config.

## Include all your tools

A config declaring a tool your app has not registered is **not delivered**. Register handlers in app code and enforce permissions there.

> **A draft must include every tool your app uses.** If you leave a tool out, the agent loses access to it on the next open after a sync, even if its handler remains registered. Omitted tools are not added back from the code config.

Keep keys and user secrets out of your config. See [AI config & Test](../studio/build.md) for the Studio steps.
