> ## 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.

# Architecture

> The mental model behind a Voyant application: modules, links, transport, jobs, and the deployment boundary.

This page explains how a Voyant application is put together. Read it once before you start building and the rest of the documentation will make more sense.

## The big idea

Voyant is a set of **headless domain modules** that you compose into an application. Each module owns one slice of the travel business, such as catalog, bookings, or finance. A module brings its own database schema, services, and HTTP routes, plus an optional React package for its UI. You pick the modules you need, wire them together with links, and deploy the result as a single application per organization.

The platform keeps a strict boundary:

* **Packages** hold reusable business logic, schemas, services, routes, and adapters. They are framework-agnostic.
* **Starters and app shells** own UI, auth wiring, deployment shape, and runtime configuration.

This means the same domain logic runs whether you deploy to your own infrastructure or to Voyant, and whether your UI is the first-party React shell or something you build yourself.

## The stack

Voyant runs as a resident Node process against Postgres. The deployable is a container image:

| Layer         | Technology                                                                   |
| ------------- | ---------------------------------------------------------------------------- |
| Runtime       | Node, long-lived resident process                                            |
| Database      | PostgreSQL, accessed through Drizzle ORM                                     |
| API transport | Hono, with optional platform route helpers                                   |
| Frontend      | TanStack Start and React                                                     |
| Auth          | Better Auth in generated projects; core packages stay auth-provider agnostic |

Core packages do not depend on any of these choices. They expose plain services and an HTTP contract, so you can host them differently if you need to.

## Modules

A **module** is a package such as `@voyant-travel/bookings` or `@voyant-travel/catalog`. Each one is self-contained:

* A Drizzle schema for its tables.
* Domain services that enforce the rules of that subdomain.
* HTTP routes exposing those services over the API.
* A matching `-react` package (for example `@voyant-travel/bookings-react`) with hooks, clients, query keys, and reusable UI.
* A contracts package (for example `@voyant-travel/bookings-contracts`) describing the wire types shared between server and client.

You add a module by installing it and registering its schema and routes, or you generate a brand new one with the CLI. See [Modules](/docs/platform/modules) for the full catalog and the generator.

## Links

Modules stay decoupled, but real travel data is relational: a person belongs to organizations, a booking references a quote, a product references a place. Voyant models these cross-module relationships with **links**.

A link is a declarative relationship between an entity in one module and an entity in another. You declare it once and the platform can emit the link table DDL for you:

```bash theme={null}
voyant generate link crm.person products.product --right-list
```

This keeps foreign-key style relationships explicit and discoverable without forcing every module to import every other module. The `voyant db sync-links` command emits the SQL or a generated Drizzle schema for all declared links.

## Transport and contracts

Every module exposes its services over HTTP using Hono. The wire shape of those routes lives in a dedicated `-contracts` package, so the server implementation and the client SDK share one source of truth for request and response types. The `-react` packages consume those contracts to give you typed hooks instead of hand-written fetch calls.

This contract-first approach is the same idea behind the public [SDKs](/docs/sdks/overview): a typed client generated against a stable API surface.

## Jobs and subscribers

Subscribers react to domain events. Package-owned jobs handle scheduled or wakeable background work and call the same domain services as routes and subscribers. The host supplies cadence, leases, retries, and health while durable domain records remain authoritative.

Selecting a package in `voyant.config.ts` selects its closed job inventory. See [Jobs](/docs/platform/jobs).

## Surfaces: storefront and admin

Two surfaces sit on top of the modules, and they are not the same shape:

* The **Public API** is the customer-facing HTTP contract under `/v1/public`: discovery, product detail, checkout, and self-service. The platform owns the contract; you own the frontend that consumes it, whether that is a Theme, the managed booking engine, or something you host yourself.
* The **admin** is the staff-facing operations console: managing quotes, bookings, inventory, finance, and the rest of the back office. It ships as a ready-made React surface assembled from the domain modules and their React packages.

Both are served by the same domain modules. See [Public API](/docs/platform/public-api) and [Admin](/docs/platform/admin).

## The deployment and security boundary

Voyant's tenancy model is deliberately simple: **one Postgres database and one runtime per organization**. Isolation is enforced at the deployment boundary, not by in-process middleware that filters rows by tenant id.

This is a foundational decision. It removes a whole class of cross-tenant data-leak bugs, keeps queries simple, and makes each customer's data physically separate. When you deploy to Voyant, the platform provisions and manages that per-organization runtime and database for you.

## Where to go next

<CardGroup cols={2}>
  <Card title="Glossary" icon="book-open" href="/docs/concepts/glossary">
    The shared travel vocabulary every module uses.
  </Card>

  <Card title="Project structure" icon="folder-tree" href="/docs/platform/project-structure">
    What a scaffolded Voyant project actually contains.
  </Card>

  <Card title="Module catalog" icon="cubes" href="/docs/platform/modules">
    Every domain module and what it owns.
  </Card>

  <Card title="Jobs" icon="clock" href="/docs/platform/jobs">
    Understand package-owned background work.
  </Card>
</CardGroup>
