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

# The model

> Declarative def objects, registered on one workspace, compiled into Xano's importable bundle.

You author declarative def-objects, register them on one `Xano` instance, and XanoTS compiles
the whole thing into Xano's importable bundle.

```ts theme={null}
import { workspace, table, query, apiGroup, f, s, ref, c, expr, col } from "@xanots/sdk";

// A database table — `id` + `created_at` auto-inject, so declare only your own columns.
const user = table({
  name: "user",
  auth: true,
  schema: {
    email: f.email({ required: true, methods: ["trim", "lower"] }),
    name:  f.text(),
  },
});

const post = table({
  name: "post",
  schema: {
    title:     f.text({ required: true }),
    body:      f.text(),
    published: f.bool({ default: false }),
    author:    f.tableRef(user),          // a real foreign key, type-checked
  },
});

// A public API group + endpoint. This query def is also the contract your frontend imports.
const blog = apiGroup({ name: "blog", canonical: "blog" });

const listPosts = query({
  verb: "GET",
  apiGroup: blog,
  name: "list_posts",
  stack: [
    s.db.query({ table: post, where: expr(col("published"), "=", c.bool(true)), as: "rows" }),
  ],
  response: ref("rows"),
});

export default workspace("blog")
  .registerApiGroups([blog])
  .registerTables([user, post])
  .registerQueries([listPosts]);
```

## Build time vs. request time

Def modules execute at **build time only**: `s.*` factories return data, and the engine runs
the compiled stack per request — statements in order, a statement's `as:` naming a runtime
variable, `response` the HTTP body. Every dynamic operand is a **tagged value** — `ref("x")` a
stack variable, `inp("x")` an input, `auth("id")` the caller, `c.*` a constant — resolved at
request time.

<Warning>
  Because operands are tagged values rather than live data, JS operators over them do **not**
  compute. Use `expr()` and the `fl.*` filter catalog instead of `+`, `&&`, or `===`.
</Warning>

Requests share no memory — state persists in tables or redis.

## The statement surface

Tab-complete `s.` to discover the entire statement catalog — `s.db.*`, `s.math.*`,
`s.array.*`, `s.text.*`, `s.storage.*`, `s.api.*`, `s.cloud.*`, control flow, AI agent runs,
and more. **All 214 engine statement surfaces are authorable** — every field name matches the
Xano engine, and the emitted shape is checked against bytes a real engine stored. Where a
surface has no stored instance behind it yet, it is built from the engine's own schema;
[Coverage](/reference/coverage) says which is which.

## Seed data

Give a table a `seed` array and those rows ship into the database on deploy, so a fresh
environment comes up with its lookup tables and fixtures already in place.

## AI agents, versioned with your code

Your workspace's own AI agents are configured the same way. `knowledge()` is the markdown they
read before they act — standing instructions, a skill, or reference docs — and the body is a
real `.md` file in your repo rather than a string in a def:

```ts theme={null}
knowledge({
  name: "deploy-runbook",
  description: "How this workspace ships: environments, gates, and rollback.",
  body: knowledgeFile("./deploy-runbook.md", import.meta.url),
  refs: knowledgeDir("./deploy-runbook", import.meta.url),
});
```

So the instructions your agents follow are reviewed in a diff, versioned with the code they
describe, and redeployed with it — instead of living in a console where nothing tracks them.

## Where to go next

Tables, fields, statements, values, inputs, and middleware are all in the
[Authoring reference](/guides/authoring); every kind you can author is in
[Object kinds](/guides/object-kinds).
