Type Generation
Generate TypeScript types from your Atlas workspace schema with @latellu/atlas-cli, so the SDK knows your content types at compile time.
Type Generation
@latellu/atlas-cli reads your workspace schema and writes a TypeScript file describing
your content types. Point @latellu/atlas-sdk at those types and your slugs,
fields, and locales become compile-time checked.
Under the hood the CLI calls GET /api/v1/public/schema on your Atlas backend. The
workspace is derived from the API key, so you never pass a workspace id — the same key you
use to read content also describes its shape.
What it generates
The CLI writes a single atlas.types.ts containing:
- one
interfaceper content type (PascalCase name derived from the slug), selectfields as string-literal unions (e.g."News" | "Event"),- a
Localeunion built from the workspace's configured locales, - an
AtlasContentTypesregistry mapping each content-type slug to its interface.
That AtlasContentTypes registry is exactly what createClient<AtlasContentTypes>() consumes.
Generate
No install step is required — run it with npx:
npx @latellu/atlas-cli generate \
--api-key=atlas_live_abc123xyz \
--output=./src/typesIf --output is a directory, the CLI writes atlas.types.ts inside it. If it ends in a
filename, that file is written instead.
Options
| Flag | Env | Default | Description |
|---|---|---|---|
--api-key | ATLAS_API_KEY | — (required) | Workspace API key. The workspace is derived from it. |
--url | ATLAS_API_URL | http://localhost:8080 | Atlas backend base URL. |
--output | ATLAS_OUTPUT | ./src/atlas.types.ts | Output file, or a directory (writes atlas.types.ts inside). |
Every flag has an environment-variable equivalent, so in CI you can keep secrets out of the command line:
export ATLAS_API_KEY=atlas_live_abc123xyz
export ATLAS_API_URL=https://api.atlas.latellu.com
export ATLAS_OUTPUT=./src/types
npx @latellu/atlas-cli generateExample output
For a workspace with one article content type and locales en and id:
// Generated by @latellu/atlas-cli — DO NOT EDIT BY HAND.
// Workspace: my-blog
export type Locale = "en" | "id";
/** Article (content type: "article") */
export interface Article {
title: string; // localizable
category?: "News" | "Event";
}
/** Maps each content-type slug to its entry interface. */
export interface AtlasContentTypes {
"article": Article;
}Wire it into the SDK
Pass the generated registry as the type parameter to createClient:
import { createClient } from '@latellu/atlas-sdk';
import type { AtlasContentTypes } from './types/atlas.types';
export const atlas = createClient<AtlasContentTypes>({
url: 'https://api.atlas.latellu.com',
apiKey: process.env.ATLAS_API_KEY!,
});
// ✅ 'article' is a known slug; post.data is typed as Article
const post = await atlas.entries('article').get('hello-world', { locale: 'en' });
// ❌ Compile error: "post" is not a content type in this workspace
await atlas.entries('post').list();See the TypeScript SDK reference for the full client API.
Keep types in sync
Regenerate after schema changes
The types reflect your schema at the moment you run generate. Whenever you add, rename, or
remove a content type or field — or change a select field's options — rerun the command so
your types match the live API again.
A common setup is a package.json script so the whole team regenerates the same way:
{
"scripts": {
"atlas:types": "atlas generate --output=./src/types"
}
}Then commit atlas.types.ts to your repo (so builds are reproducible) and run
npm run atlas:types whenever the schema changes.
Current limitations
- Localizable fields are typed as their base value in this release; a per-locale
representation is planned alongside
@latellu/atlas-sdk. The runtime locale merge still applies — see TypeScript SDK → Entries.