Migrate from experimental TypeGen in the App SDK
Upgrade an App SDK app from the deprecated experimental TypeGen packages to released groq and typegen.resources.
Before App SDK 3.9.0, TypeGen support for the App SDK came from experimental builds of @sanity/cli and groq (versions such as 3.88.1-typegen-experimental.0, configured with unstable_schemas in sanity-typegen.json). Those builds are deprecated. The current workflow uses typegen.resources in sanity.cli.ts, described in App SDK and TypeGen.
This guide covers two stages. The first keeps your saved sanity.types.ts working on released packages, so you can upgrade without changing your types. The second moves the app to typegen.resources, which you need before you can change schemas or queries again.
TypeGen support for the App SDK is in beta. typegen.resources, the SDK's type resolvers, and defineProjection with a document type can change in minor releases.
Prerequisites
@sanity/sdk-reactand@sanity/sdk3.9.0 or later.groq6.15.0 or later.@sanity/cli8.16.0 or later, to move totypegen.resources.
Keep the saved types file working
A sanity.types.ts generated by the experimental packages imports helper types such as SchemaOrigin from groq. App SDK 3.9.0 and later supply compatibility declarations for those imports, so the saved file keeps working with released groq while you migrate.
- Keep a copy of your existing
sanity.types.ts. Stop any install or build script that regenerates it with the experimental CLI, such as atypegenscript that runs./node_modules/@sanity/cli/bin/sanity typegen generate. - Replace the experimental
groqdependency with releasedgroq:npm install groq@^6.15.0. If you added a"groq": "$groq"entry tooverridesfor the experimental setup, it now resolves to the released version. - Remove the experimental
@sanity/clidependency, including any alias you used to install it beside the current CLI. - Import
defineProjectionfrom an App SDK package instead ofgroq: changeimport {defineProjection} from 'groq'toimport {defineProjection} from '@sanity/sdk-react'(or@sanity/sdk).defineQuerystill comes fromgroq. Keep existing query and projection strings unchanged, so they match the entries in your saved file. - Check your dependency tree and type-check the app:
npm ls groq
npx tsc --noEmitnpm ls groq
pnpm dlx tsc --noEmitnpm ls groq
yarn dlx tsc --noEmitnpm ls groq
bunx tsc --noEmitYour generated file and the SDK must resolve the same released groq declarations. When they don't, TypeScript reports errors such as Module '"groq"' has no exported member 'SchemaOrigin' in the saved file, and hook results are typed as never (for example, Property 'title' does not exist on type 'never'). To fix this, align the app and SDK versions and update the lockfile. Keeping the experimental groq build alongside released groq isn't supported.
The saved file doesn't update. To change schemas or queries, move to typegen.resources.
Move to per-dataset types with typegen.resources
Make this move in one change, so old and new type registrations don't exist side by side:
- Install
@sanity/cli8.16.0 or later, and configure each dataset undertypegen.resourcesas described in App SDK and TypeGen. - Check which CLI version runs:
npx sanity --version. Thesanitypackage depends on@sanity/cli, and your lockfile can still resolve an older version. A CLI earlier than 8.16.0 ignorestypegen.resourcesand fails withSchema file not found: …/schema.json - did you run "sanity schema extract"?If it reports an earlier version, runnpm install --save-dev @sanity/cli@^8.16.0. - Add the document type as the first argument to each
defineProjectioncall, as indefineProjection('book', '{title}'). Keep the query and projection text otherwise unchanged. - Delete
sanity-typegen.json. While it exists, the CLI still usessanity.cli.ts, but first warnsYou've specified typegen in your Sanity CLI config, but also have a typegen config. - Run
npx sanity typegen generate. - Delete the saved
sanity.types.ts, or remove the saved file from your TypeScript program. While both files exist, a handle without a literal dataset gets the union of the old and new types. - Update imports of generated types to the file for each dataset. A type that the old file shared across datasets becomes one export per file.
- Type-check the app, and check the screens that read documents, run queries, and show projections.
Troubleshoot the migration
These errors can appear when you run npx sanity typegen generate after moving to per-dataset types:
Schema file not found: …/schema.json - did you run "sanity schema extract"?: The CLI that runs is earlier than 8.16.0, so it ignorestypegen.resources. Check the version withnpx sanity --version, and install a newer CLI withnpm install --save-dev @sanity/cli@^8.16.0.No schema is bound to dataset: The resource has noschemafile, and the CLI couldn't fetch a bound schema for the dataset. Check the resource'sprojectIdanddataset, or extract the schema withnpx sanity schema extractand setschemaon that resource.Duplicate query name found: Two scanned files define a query with the same variable name. Query names must be unique across all scanned files, so rename one of them.
Next steps
- To type documents, queries, and projections with your generated files, see App SDK and TypeGen.
- To generate types for a studio or front end, see Sanity TypeGen.
Was this page helpful?
Feedback submitted, thanks for helping us improve the docs. Have you tried these alternatives?