> ## Documentation Index
> Fetch the complete documentation index at: https://voyant.travel/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> The voyant.config.ts manifest: what it declares, how the platform reads it to assemble schemas, routes, and admin, and the inspect, validate, and doctor commands that keep a deployment honest.

A Voyant deployment is described by one manifest: **`voyant.config.ts`**. It is the single declaration of what the deployment is, and the platform reads it to assemble the app at build time. This page explains what the manifest declares, how the platform turns it into a running app, and the CLI commands that inspect and gate it. Configuration is the seam that lets a deployment shrink to its identity (its config, the providers it chose, and the small amount it added) instead of being a fork full of hand-maintained glue.

## What the manifest declares

`voyant.config.ts` describes **only the differences from the standard product**. It expands the versioned `@voyant-travel/operator-standard` distribution and merges your project-specific changes on top.

| Key          | What it declares                                                                                                                     |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `deployment` | The target (`node`), the mode (`local`, `self-hosted`, or `managed-cloud`), and the infrastructure `providers` the deployment binds. |
| `plugins`    | Reusable distribution bundles the application deliberately installs, each `{ resolve, config }`.                                     |

<Warning>
  **A standard project does not list standard modules.** It also does not list package-owned extensions, admin pages, API documents, subscribers, jobs, links, migrations, or runtime bindings. Those come from the product distribution. Product defaults change through an explicit distribution dependency or lockfile change, so graph diffs and migration plans stay reviewable.
</Warning>

```ts theme={null}
// voyant.config.ts
import { defineConfig } from "@voyant-travel/framework/project"

export default defineConfig({
  plugins: [
    {
      resolve: "@acme/voyant-payment-provider",
      config: { merchantAccount: "travel" },
    },
  ],
  deployment: {
    target: "node",
    mode: "self-hosted",
    providers: {
      database: "postgres",
      cache: "redis",
    },
  },
})
```

A clean application may contain only `package.json`, `voyant.config.ts`, environment configuration, and the Node bootstrap.

### Project-local contributions

Local behavior is added by creating files in conventional directories, discovered at build time rather than enumerated in the manifest:

```text theme={null}
src/
  api/
    admin/
    public/
  admin/
  modules/
  extensions/
  subscribers/
  links/
```

A package-owned extension is never repeated as a project plugin.

## How the platform reads it

The manifest is not decoration. The build resolves it into a complete
`voyant.resolved-graph.v1` artifact and lowers that graph to **one resident Node
application**. Package-owned `voyant.package.v1` manifests are the authority for
product behavior; neither the project nor the Node host reconstructs that
behavior in a parallel catalog.

<Steps>
  <Step title="Resolve the graph">
    The versioned product distribution plus your differences resolve into the
    complete application graph. Modules are components of that one deployable,
    not deployment units: there is no `exclude`, and a deployment cannot drop or
    substitute a standard module.
  </Step>

  <Step title="Derive schemas and migrations">
    The resolved graph determines the schema set and migration plan. It is
    *derived*, never hand-listed, so a graph diff is reviewable before it runs.
  </Step>

  <Step title="Bind providers at boot">
    Infrastructure provider bindings are selected at boot inside the fixed
    graph. Swapping a database, cache, or object-storage implementation never
    changes the graph shape.
  </Step>
</Steps>

<Note>
  A standard deployment upgrades by bumping the distribution version and running
  migrations, with no code merge, because the graph and provider bindings are
  stable contracts and platform changes arrive as package updates. Custom
  deployments do the same and reconcile only their own `src/` contributions.
</Note>

## Inspecting the manifest

The CLI reads the nearest `voyant.config.*` and can show it, validate it, or tell you which file resolved.

```bash theme={null}
voyant config show       # print the resolved manifest
voyant config validate   # validate the manifest
voyant config path       # show which voyant.config.* file resolved
```

Reach for `voyant config path` first when a deployment is behaving as if it read a different manifest than you expect (a common surprise in a workspace with multiple config files). `voyant config validate` checks the manifest is well-formed before you rely on anything derived from it.

To inspect what the manifest *derives* on the database side, use the schema and admin commands:

```bash theme={null}
voyant db schemas          # print the manifest-derived schema list
voyant db schemas --emit    # emit the generated schema manifest
voyant admin generate --check        # verify admin extensions are in sync
voyant admin generate --routes --check
voyant admin generate --destinations --check
```

The `--check` forms verify the generated artifacts are in sync with the manifest without rewriting them, which is what you want in CI.

## The doctor preflight gates

`voyant doctor` is the single preflight that makes a deployment safe to run and to upgrade. It runs a set of gates and exits non-zero on any failure.

```bash theme={null}
voyant doctor            # run all preflight gates
voyant doctor --strict   # treat warnings as failures
```

It closes the cheapest, highest-value risks:

* **Env, bindings, and secrets.** It validates required env at startup instead of letting a missing value fail at first use as a runtime 500, and it checks `env.d.ts` against `wrangler.jsonc` (including catching placeholder values like unreplaced KV ids).
* **Composition drift.** It asserts that `config.modules`, the mounted registry, the derived nav, icons, and destinations, and the generated routes are all in sync, and that every installed module's migrations are applied. A module present in `config.modules` but missing an icon, label, destination, or migration fails the gate. This is what keeps an upstream domain from silently vanishing from the nav on upgrade.

Under the hood it composes the narrower doctors, so you can also run them individually:

```bash theme={null}
voyant db doctor --fail-on-drift   # manifest resolvability, schema parity, prefixes, link snapshot
voyant admin doctor                # parity between manifest, admin extensions, and routes/destinations
```

<Tip>
  Make `voyant doctor` part of CI and run it locally before pushing. It is cheap, independent of the heavier framework machinery, and it is the mechanism that turns "bump versions and migrate" into a safe upgrade rather than a leap of faith.
</Tip>

## Admin generation from the manifest

The dashboard is assembled from the manifest, not hand-registered. `voyant admin generate` emits the generated admin artifacts so adding a module to `config.modules` contributes its admin presence automatically.

```bash theme={null}
voyant admin generate                 # emit admin.extensions.generated.ts
voyant admin generate --routes        # emit the assembled admin route module
voyant admin generate --destinations  # emit the destination resolver map
```

Custom admin surfaces a deployment adds (a page, a widget injected into a named slot, or a nav entry) are discovered from `src/admin/<name>/` rather than declared in the manifest, the same drop-a-folder build-time discovery used for extensions. So the manifest stays the source of truth for the *standard* admin, while the deployment's own admin additions live in code it owns and that survives `voyant upgrade`.

## Next steps

<CardGroup cols={2}>
  <Card title="Modules" icon="cubes" href="/docs/concepts/how-it-is-built">
    What the manifest's `modules` actually compose.
  </Card>

  <Card title="Data models" icon="table" href="/docs/concepts/how-it-is-built">
    How the manifest derives the schema set and migrations.
  </Card>

  <Card title="Architecture" icon="sitemap" href="/docs/platform/fundamentals/architecture">
    Build-time composition and the deployment boundary.
  </Card>

  <Card title="Command reference" icon="terminal" href="/docs/cli/commands">
    Every `voyant config`, `voyant admin`, and `voyant doctor` command.
  </Card>
</CardGroup>
