DatoCMS CLI

Generating TypeScript types from your schema

DatoCMS records don't have a predetermined structure, so the JavaScript CMA client cannot provide strict TypeScript types out of the box: every field comes back typed as unknown. To get full type-safety, auto-completions, and inline type hints in your editor, the CLI exposes a schema:generate command that reads your project's schema and emits a TypeScript definition file describing every model and block.

The command

After installing and linking the CLI, generate the schema with:

Terminal window
npx datocms schema:generate schema.ts

The output is a TypeScript module you commit to your repo and import wherever you call the CMA client.

What gets generated

For each model and block in your project, the command emits an ItemTypeDefinition type (used as a generic in CMA calls) and a runtime constant (used to reference the model's ID or build relationships):

// schema.ts: generated by `npx datocms schema:generate`.
//
// Do not hand-edit. Re-run the generator whenever the schema changes.
import type { ItemTypeDefinition } from '@datocms/cma-client';
type EnvironmentSettings = { locales: 'en' | 'it' };
export type Article = ItemTypeDefinition<
EnvironmentSettings,
'76hhD-LaS5CM3NPJw0991w',
{
name: { type: 'string' };
slug: { type: 'slug' };
accent_color: { type: 'color' };
sections: { type: 'rich_text'; blocks: ArticleSection };
}
>;
export const Article = {
ID: '76hhD-LaS5CM3NPJw0991w',
REF: { type: 'item_type', id: '76hhD-LaS5CM3NPJw0991w' },
} as const;

The generated file then turns calls like client.items.find<Schema.Article>(id) into fully typed expressions. For the full set of patterns (using markers in API calls, extracting concrete field types, narrowing block unions, typing whole payloads), see Type-safe development with TypeScript in the CMA section.

Two ways to generate the schema

The CLI lets you generate types in two complementary ways, depending on how you plan to use them.

Standalone: for your application code

The most common case: a single schema.ts file in your repo that your application code imports.

Terminal window
npx datocms schema:generate ./src/datocms-schema.ts

You typically commit this file and re-run the command whenever the project schema changes.

Inline: within a migration script

A migration script represents the schema at a specific point in its history: its job is to take the project from state N to state N+1. The standalone schema.ts file, on the other hand, always reflects the latest state of the project. If a migration written six months ago referenced Schema.Article from the global file, and Article has since been renamed or restructured, the migration would silently start type-checking against a schema it was never written for.

To keep a migration type-safe against its own historical view of the project, the CLI can inline the relevant model definitions directly into the migration file at scaffold time:

Terminal window
npx datocms migrations:new 'tweak articles' --schema=Article,Author

Use --schema=all to inline every model. The migration ends up self-contained: it carries its own snapshot of the schema, decoupled from the global schema.ts, and continues to type-check correctly even after the project schema evolves.

Targeting a specific subset

Two flags narrow what gets generated:

  • --item-types=product,article: generate only the listed models. Useful when your project has hundreds of models and you only need a few in your app.

  • --environment=my-sandbox: generate from a specific sandbox environment instead of primary. Useful when previewing a schema change before promotion.

Keeping types in sync

The generated file is only as fresh as the last schema:generate run. If your project schema changes (a new model, a renamed field) and you forget to regenerate, your TypeScript types will silently drift from the actual API shape.

A common pattern is to automate the regeneration: a nightly CI job (or a webhook triggered on schema changes) runs npx datocms schema:generate and opens a pull request whenever the output differs from the version in git. That way the types in your repo are always one merge away from being correct, and any drift is visible at code review time.

Pro tip: Want this fully automated?

Installing Agent Skills gives a coding agent the knowledge to scaffold migrations when you change the schema, regenerate types, and decide between a migration script and a direct CMA mutation for any given schema change — on top of everything this CLI does.

Last updated: