Skip to main content
View as Markdown

TypeScript Configs

A config can be a TypeScript module instead of a YAML or JSON file. The CLI takes app.ts everywhere it takes app.yaml — the difference is entirely in your editor, where every property, field type and component type is checked as you type.

@sovrium/types

The types come from a separate package, so authoring a config never pulls the engine into your project.

bun add -d @sovrium/types
// 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 },
      ],
    },
  ],
})
sovrium start app.ts
sovrium validate app.ts

defineConfig is an identity function: it returns its argument untouched and annotates it as AppConfig. That is all it needs to do — the annotation is what makes an invalid field type, an unknown component type, or a missing required property an error at the keystroke rather than at boot.

Composing with imports

$ref is a YAML/JSON mechanism; TypeScript already has one. Split sections into modules and assemble them in defineConfig:

// config/tables.ts
import type { TableConfig } from '@sovrium/types'

export const companies: TableConfig = {
  id: 1,
  name: 'Companies',
  fields: [
    { id: 1, name: 'name', type: 'single-line-text', required: true },
    { id: 2, name: 'website', type: 'url' },
  ],
}
// app.ts
import { defineConfig } from '@sovrium/types'
import { companies } from './config/tables'

export default defineConfig({
  name: 'crm-workspace',
  tables: [companies],
})

Because it is a real module, the config can also be computed — read a value from the environment, generate a table per entity, derive routes from a list.

When to prefer TypeScript

Choose TypeScript when Choose YAML when
The config is large enough that typos cost real debugging time The config is small and read more often than edited
Sections repeat and you would rather generate than copy Non-developers need to read or amend it
Values come from the environment or another source You want the file to be obviously data, not code
You want errors in the editor rather than at sovrium validate You want it diffable and reviewable without a build

Both are the same object, so this is not a one-way door: a YAML config transcribes to TypeScript by hand, and vice versa.

Last updated July 27, 2026

This documentation was written with AI, so errors or outdated content are possible. Sovrium is in beta — contributions and corrections are welcome.

Built with Sovrium