
# Configuration Files

Sovrium loads your application from a configuration file. The same configuration object can be written as YAML, JSON, or TypeScript, split across many files with `$ref`, and checked ahead of time with `sovrium validate`.

## YAML and JSON

The simplest configuration is a YAML or JSON file. YAML is recommended for hand-authoring — it supports comments, requires less punctuation, and is easier to read. JSON is convenient when generating configs programmatically.

```yaml
# app.yaml
name: my-app
version: 1.0.0
description: A simple todo list

tables:
  - id: 1
    name: tasks
    fields:
      - { id: 1, name: title, type: single-line-text, required: true }
      - { id: 2, name: done, type: checkbox, default: false }
```

```json
{
  "name": "my-app",
  "version": "1.0.0",
  "description": "A simple todo list",
  "tables": [
    {
      "id": 1,
      "name": "tasks",
      "fields": [
        { "id": 1, "name": "title", "type": "single-line-text", "required": true },
        { "id": 2, "name": "done", "type": "checkbox", "default": false }
      ]
    }
  ]
}
```

Run either with the CLI:

```bash
sovrium start app.yaml
sovrium start app.json
```

:::callout
**Format detection is by extension.** Sovrium routes `.yaml`/`.yml` files through its YAML parser and `.json` files through its JSON parser. The shape of the resulting object is identical — every example in this documentation can be transcribed between the two formats.
:::

## TypeScript with `defineConfig`

For full type safety and IDE autocompletion, author your config in TypeScript and validate it against the `@sovrium/types` package. `@sovrium/types` is a **zero-dependency** package of TypeScript types extracted directly from the Sovrium schema.

```bash
bun add -d @sovrium/types
```

```typescript
// app.ts
import { defineConfig } from '@sovrium/types'

export default defineConfig({
  name: 'my-app',
  version: '1.0.0',
  description: 'A simple todo list',
  tables: [
    {
      id: 1,
      name: 'tasks',
      fields: [
        { id: 1, name: 'title', type: 'single-line-text', required: true },
        { id: 2, name: 'done', type: 'checkbox', default: false },
      ],
    },
  ],
})
```

```bash
sovrium start app.ts
sovrium validate app.ts
```

`defineConfig` is an identity helper: it returns its argument unchanged but annotates it with the `AppConfig` type, so your editor reports invalid field types, unknown component types, and missing required properties as you type — no separate type import or `satisfies` needed.

:::callout
**`@sovrium/types` vs the `sovrium` package.** `@sovrium/types` ships only types (MIT-licensed, zero runtime). Use it to author config files. To run Sovrium programmatically (`import { start } from 'sovrium'`), see the [TypeScript API](/en/docs/typescript).
:::

## Multi-file configs with `$ref`

As an app grows, a single file becomes unwieldy. Sovrium supports `$ref` to split configuration across multiple files. Any object containing exactly one key, `$ref`, whose value is a relative path, is replaced with the parsed contents of that file before validation.

```yaml
# app.yaml
name: crm-workspace
version: 2.0.0

auth:
  $ref: ./config/auth.yaml

theme:
  $ref: ./config/theme.yaml

tables:
  - $ref: ./config/tables/companies.yaml
  - $ref: ./config/tables/contacts.yaml
  - $ref: ./config/tables/deals.yaml

pages:
  - $ref: ./config/pages/sign-in.yaml
  - $ref: ./config/pages/companies.yaml

agents:
  - $ref: ./config/agents/records-assistant.yaml
```

```yaml
# config/tables/companies.yaml
id: 1
name: Companies
fields:
  - { id: 1, name: name, type: single-line-text, required: true }
  - { id: 2, name: website, type: url }
```

| Rule              | Behavior                                                                                                       |
| ----------------- | -------------------------------------------------------------------------------------------------------------- |
| Path resolution   | `$ref` paths resolve relative to the file that contains them, not the working directory.                       |
| Mixed formats     | A YAML root file may `$ref` a JSON partial and vice versa — each file is parsed by its extension.              |
| Array elements    | A `$ref` can stand in for a whole array element (`- $ref: ...`) or a whole object value.                       |
| Resolution timing | All `$ref`s are resolved into one object _before_ schema validation, so cross-section checks see the full app. |

:::callout
**TypeScript configs compose differently.** `$ref` is a YAML/JSON mechanism. In TypeScript you compose with ordinary `import`s — define sub-configs in separate modules and assemble them inside `defineConfig({ ... })`.
:::

## Loading without a file

Configuration can also come from the `APP_SCHEMA` environment variable instead of a file path — inline JSON, inline YAML, or a remote URL. See the [CLI Reference](/en/docs/cli#configuration-sources) for details.

## Validating a config

`sovrium validate` checks a config file against the full app schema — including cross-section rules such as "a record automation must reference an existing table" — and returns a non-zero exit code with error details when something is wrong.

```bash
sovrium validate app.yaml
sovrium validate app.ts
sovrium validate config.json
```

Run it in CI to catch configuration errors before deployment. Because validation runs the same schema the server uses at boot, a config that passes `validate` is guaranteed to start.

## Next steps

- [Core Concepts](/en/docs/concepts) — the anatomy of the configuration object.
- [CLI Reference](/en/docs/cli) — every command, flag, and configuration source.
- [TypeScript API](/en/docs/typescript) — running Sovrium as a library.
- [Schema Overview](/en/docs/overview) — the full root-property reference.
