Sanity TypeGen is now generally available
TypeGen generates exact TypeScript types from your schemas and queries. So AI tools stop guessing and developers stop debugging phantom fields.

Kristoffer Brabrand
Senior Software Engineer

Sindre Gulseth
Staff Software Engineer

Knut Melvær
Principal Developer Marketing Manager
Published
Table of Contents
- Types that stay in sync while coding
- One config file, not two
- Faster generation (with a progress bar, finally)
- Smarter generated output
- Type utilities for real-world schemas
- Framework support beyond Next.js
- What “GA” means (and what it doesn't)
- Getting started
- Migrating from the beta
- Everything that changed since beta
AI coding tools are only as good as the context you give them. Point Claude, Cursor, or Copilot at vague, or no, types and you get vague suggestions. Give them precise types and they autocomplete correctly, catch edge cases, and stop hallucinating field names.
Sanity TypeGen generates precise TypeScript types from your content schemas and GROQ queries. Which means that you (and your agents) get the most out of the flexbility of GROQ, without losing the power of a well-defined schema. Few, if any, CMSes out there give you this developer experience.
So instead of event.format: string, you get 'in-person' | 'virtual'. Instead of post.coverImage: any, you get the full image structure with asset reference and optional alt text. Your editor autocompletes GROQ projections. Your AI assistant stops inventing fields (🤞). Your types stay in sync with your content model.
TypeGen is now generally available in Sanity Studio v5 with automatic regeneration, consolidated configuration, and stable APIs. If you used the beta, the migration is straightforward, the breaking changes are intentional improvements that make generated types more accurate.
Types that stay in sync while coding
The most requested feature during the beta was automation. Manually running sanity schema extract and sanity typegen generate every time you changed a schema or query worked, but it was easy to forget and end up with stale types.
Now you can turn on automatic type generation with a single config option. When you enable typegen.enabled: true, TypeGen will run automatically during sanity dev:
// sanity.cli.ts
import { defineCliConfig } from 'sanity/cli'
export default defineCliConfig({
// …your project config
typegen: {
enabled: true,
},
})Running sanity dev now watches your schema and query files automatically. If you're running a separate frontend repo, use the --watch flag:
sanity typegen generate --watch
One config file, not two
TypeGen originally had sanity-typegen.json for configuration. Now everything lives in sanity.cli.ts alongside your other CLI settings.
// sanity.cli.ts
import { defineCliConfig } from 'sanity/cli'
export default defineCliConfig({
// …your project config
typegen: {
enabled: true,
path: './sanity.types.ts',
schema: './schema.json',
generates: {
'./src/types.ts': {
// custom generation options
},
},
overloadClientMethods: true,
},
})The old config file still works but now shows a deprecation warning.
One caveat: if you’re in a mono repo where the studio and other apps are in different packages, you'll still need the JSON schema for those:
- Enable
schemaExtraction.enabled: truein the studio'ssanity.cli.tsto produce theschema.json. - Then point your frontend/apps repo's typegen config at that generated schema file.
Faster generation (with a progress bar, finally)
We rewrote the type generation internals with memoization, so updates in watch mode are significantly faster. You'll also see a progress indicator during generation so you know it's working. (No, we can’t promise we have finaly solved the halting problem.)
Smarter generated output
The generated types are now more accurate and easier to work with:
- Preserved casing: A query named
MyPageQuerynow producesMyPageQueryResultinstead ofMypagequeryResult - Correct non-identifier keys: Fields with kebab-case or special characters are now properly quoted
// Before
type Post = {
my-field: string // ❌ Invalid TypeScript
}
// After
type Post = {
'my-field': string // ✅ Properly quoted
}- Smaller output: Array types now use an
ArrayOfutility type, reducing duplication and file size
Type utilities for real-world schemas
Two new utility types make it easier to work with complex content models. This is especially handy for landing page-type content that tends to get nested.
The Get utility extracts deeply nested properties (up to 20 levels):
import type { Get } from '@sanity/codegen'
import type { Page } from './sanity.types'
// Extract a deeply nested type
type HeroSection = Get<Page, 'sections', number, 'hero'>
// No more juggling NonNullable and index access
type OldWay = NonNullable<NonNullable<NonNullable<Page>['sections']>[number]>['hero']The FilterByType utility pulls specific types from unions using the _type discriminator:
import type { FilterByType } from '@sanity/codegen'
import type { PageBuilder } from './sanity.types'
// Extract only hero blocks from a union of block types
type HeroBlock = FilterByType<PageBuilder, 'hero'>
// Works with multiple types too
type ContentBlocks = FilterByType<PageBuilder, 'hero' | 'textBlock' | 'imageGallery'>Framework support beyond Next.js
The TypeGen tooling now supports @sanity/sveltekit defineQuery imports and can parse .svelte and .vue files. Support for .astro files was already available.
What “GA” means (and what it doesn't)
General availability means the TypeGen APIs are stable. The configuration format, CLI commands, and utility types won't change in breaking ways. Generated output will continue to improve, but those improvements will remain compatible with your existing code.
Some limitations remain:
- Cross-dataset references and some complex GROQ expressions still type as
unknown
Getting started
Setup depends on your project structure. Here are the three most common scenarios:
If you're running sanity dev or sanity build in your studio
In your studio, you typically want schema extraction enabled to generate the schema.json file. If you only need the schema.json (for example, to use in other packages), enable schemaExtraction.enabled: true. If you also need types in your studio code (for custom components, etc.), add typegen.enabled: true as well. Both control whether these processes run as part of sanity dev and sanity build commands.
// sanity.cli.ts
import { defineCliConfig } from 'sanity/cli'
export default defineCliConfig({
// …your project config
schemaExtraction: {
enabled: true,
},
typegen: {
enabled: true,
},
})Monorepo with separate studio and frontend packages
In your studio's sanity.cli.ts, enable schemaExtraction.enabled: true to generate the schema.json file when you run sanity dev or sanity build. Add typegen.enabled: true if you also want to generate types for use in the studio itself.
In your frontend packages, run sanity typegen generate --watch and configure the path to point to the schema.json generated by the studio. Since frontend repos don't use sanity dev or sanity build, you run the typegen command directly with the --watch flag for automatic regeneration during development.
Studio embedded in another app
If your Studio is embedded on an app route (Next.js, Astro, Nuxt, etc.), you're not using sanity dev or sanity build to build your app. This means the enabled flags won't help you. Instead, you'll need to run the CLI commands directly:
sanity schema extractto generate the schema JSONsanity typegen generateto create types (use--watchfor automatic regeneration during development)
Migrating from the beta
If you're using the beta, here's the migration path:
- Update to Sanity Studio v5
- Move config from
sanity-typegen.jsontosanity.cli.ts - Regenerate types (expect diffs due to improvements)
- Enable automatic generation with
enabled: true
The breaking changes are intentional corrections that make the generated types more accurate.
Everything that changed since beta
Here’s the smørgåsbord of most of the things we improved:
- Automatic type generation during
sanity devandsanity build - Configuration moved to
sanity.cli.ts - Progress indicator during generation
- Memoization for faster watch mode updates
- Preserved casing in generated type names
- Proper quoting for non-identifier keys
ArrayOfutility type for smaller outputGetutility for extracting nested types (up to 20 levels)FilterByTypeutility for filtering union types- Support for
@sanity/sveltekitdefineQuery - Parsing support for
.svelteand.vuefiles @sanity-typegen-ignorecomment support- Stable API surface (no more breaking changes planned)
The Sanity Learn course has been updated to reflect all these changes. If you're new to TypeGen or want to see the latest features in action, it's a great place to start.
Thanks to Kristoffer Brabrand, Rico Kahler, and Sindre Gulseth for the work here. And to everyone who tested the beta and provided feedback. If you run into issues or have suggestions, join us in the #typescript channel in the Sanity community Discord.