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

# Feature schemas

> Version CMS content types, forms, and App Data tables as JSON with schemasDir and webstorio schema.

Use **feature schemas** to keep Content & CMS types, Form & Survey forms, and
App Data tables in your repo — then sync them with the CLI.

## Enable schemas in config

Set `schemasDir` in `webstorio.config.ts` (relative to the config file):

```ts theme={"dark"}
export default defineConfig({
  // ...
  schemasDir: "schemas",
  features: {
    content: true,
    form_and_survey: true,
    app_data: true,
    // ...
  },
});
```

Enable the matching [website features](/guides/website-features) before syncing
that kind (`content`, `form_and_survey`, `app_data`).

## Folder layout

```text theme={"dark"}
schemas/
├─ content/     # CMS content types
├─ forms/       # Form & Survey forms
└─ data/        # App Data tables
```

Each `*.json` file is one definition, upserted by **`key`**.

## File shape

```json theme={"dark"}
{
  "version": 1,
  "kind": "content_type",
  "key": "post",
  "name": "Blog Post",
  "description": "Optional",
  "schemaJson": [
    { "key": "title", "type": "text", "label": "Title", "required": true }
  ],
  "settingsJson": {}
}
```

| Field          | Notes                                                                                         |
| -------------- | --------------------------------------------------------------------------------------------- |
| `version`      | Always `1`                                                                                    |
| `kind`         | `content_type`, `form`, or `data_model` — optional when the file is under the matching folder |
| `key`          | Stable id: lowercase letter start, then `a-z`, `0-9`, `-`, `_`                                |
| `name`         | Display name                                                                                  |
| `schemaJson`   | Field/column definitions (array)                                                              |
| `settingsJson` | Optional settings object (forms often use this)                                               |

Forms may also use the dashboard export shape:

```json theme={"dark"}
{
  "version": 1,
  "form": {
    "key": "contact",
    "name": "Contact",
    "schemaJson": [],
    "settingsJson": {}
  }
}
```

Full `schemasDir` notes: [Configuration](/cli/configuration#schemasdir).

## Commands

```bash theme={"dark"}
npx webstorio schema pull    # download remote → schemasDir
npx webstorio schema diff    # read-only local vs remote
npx webstorio schema push    # upsert local → remote
npx webstorio schema push --prune   # also delete remote keys missing locally
```

| Subcommand | Purpose                                                          |
| ---------- | ---------------------------------------------------------------- |
| `pull`     | Write remote schemas into `schemas/content`, `forms`, and `data` |
| `diff`     | Show `new` / `modified` / `unchanged` / `remote_only`            |
| `push`     | Upsert by `key` (same sync used after pages on `webstorio push`) |

`--prune` (and `webstorio push --prune-schemas`) **deletes** remote schemas whose
keys are not present locally — use carefully.

Options reference: [`webstorio schema`](/cli/commands#webstorio-schema).

## How this fits with `push`

When `schemasDir` is set:

1. `webstorio push` syncs pages/components/features/branding as usual.
2. Then it upserts local schemas (unless you manage them only with
   `webstorio schema push`).

When `schemasDir` is **absent**, remote CMS / form / App Data definitions are
left unchanged.

`webstorio status` also diffs schemas when `schemasDir` is set — see
[Deploying](/developer/deploying#2-check-status).

## Typical workflow

1. Enable features and set `schemasDir: "schemas"`.
2. `npx webstorio schema pull` (or author JSON files by hand).
3. Edit fields locally; `npx webstorio schema diff` to review.
4. `npx webstorio schema push` — or include schemas in a normal
   `npx webstorio push`.

Page code still reads live data through the [Client SDK](/api-reference/sdk/overview)
(`getContentEntries`, `getFormSchema`, App Data methods, and so on).
