App SDK

App SDK and TypeGen

Learn how to use Sanity TypeGen with the App SDK for increased type safety and improved developer experience.

Sanity TypeGen is a tool that generates TypeScript types directly from your Sanity schemas and GROQ queries. When used with the Sanity App SDK, it provides strong type safety and autocompletion suggestions for your documents, query results, and projections.

In this guide, we’ll walk through setting up and using TypeGen within your SDK app.

Experimental feature

Setup

Using Typegen involves two main steps: extracting your schema(s) and then generating the types. Both commands are available via the CLI.

Extract schemas

First, you need to extract your Sanity schema(s) into a JSON format that Typegen can understand. Currently, this step relies on the full sanity package, typically used within your Sanity Studio project, as Typegen needs access to the complete schema definition to generate accurate types.

Schema extraction is performed within your Studio setup to generate the schema.json file. Once created, this file can be used independently by other tools or parts of your workflow.

Use the sanity schema extract command within your Studio project or a project that has the sanity package installed:

This schema.json file can be copied to (or the --output-path can be set directly to) your Sanity app's repository. Your application itself does not need the full sanity package as a dependency to use the generated types; it only needs the schema.json file for the typegen generate step.

If your Studio project defines multiple workspaces or you need types for different schemas (e.g., for different datasets), run the extract command for each one, outputting to separate JSON files. For example, you could configure you Studio’s package.json as follows:

We plan to improve this schema extraction process as the SDK matures to potentially reduce the dependencies and improve overall developer experience.

Install (experimental) packages

To use the Typegen features described in this guide, your SDK app needs specific experimental versions of @sanity/cli and groq installed. Install these packages from within your SDK app directory:

Package names and installation

Configure TypeGen (optional)

For the most common use case – a single Sanity schema for your project – no configuration file is needed. However, you'll need to create a TypeGen configuration file for more complex use cases, such as:

  • Using multiple schemas (e.g., from different workspaces or for different datasets).
  • Needing to explicitly map a single schema to a specific schemaId for accurate schema scoping (instead of using the default 'default').
  • Using a different name or location for your schema file(s).
  • Specifying a custom output path for the generated types file.

If you need this level of configuration, create a TypeGen configuration file (sanity-typegen.json ) at the root of your SDK app and use the unstable_schemas array:

Objects in the unstable_schemas array each consist of the following properties:

  • schemaPath: The path (relative to the project root) to the corresponding extracted schema JSON file.
  • schemaId: A string combining your projectId and dataset (e.g., "your-project-id.your-dataset-name"). This is used to map the schema to the correct project and dataset context for type generation, as the extracted schema.json doesn't contain this information itself.

The optional outputPath property specifies where to write the generated sanity.types.ts file. It defaults to the project root.

By default, TypeGen works seamlessly for the common single-schema setup without extra configuration. Use sanity-typegen.json only when your needs require more explicit control.

Generate types

With the necessary packages installed and your schema(s) extracted (and optionally configured in sanity-typegen.json), you can run the sanity typegen generate command from within your SDK app directory:

This command reads your configuration (either sanity-typegen.json or the default schema.json), processes the specified schemas, and generates a sanity.types.ts file, which contains your types. It's recommended to add this command to your SDK app’s package.json scripts. For example:

Congratulations! You’ve now generated types for your schema documents, projections, and query results. With your sanity.types.ts file in place, the App SDK hooks will automatically pick up these types.

Next, we’ll cover how to make use of these generated types in your SDK app.

Use the generated types

TypeGen generates interfaces for each document type defined in your schemas. For projects using multiple schemas/datasets defined in sanity-typegen.json, it utilizes a helper type SchemaOrigin (imported from groq) to brand the types.

This allows TypeScript to narrow down the possible document types based on the dataset context provided via a DocumentHandle. See the code below for an example of this:

Handles and literal types

For TypeGen to correctly infer types in hooks like useDocument, it needs to know the specific literal type of the documentType (e.g., 'book' instead of just string).

The App SDK provides helper functions (like createDocumentHandle and createDatasetHandle) that help capture these literal types:

Alternatively, if you prefer defining handles as plain objects, use as const to ensure the documentType has the literal type of 'book':

Document projections

To get types for GROQ projections used with useDocumentProjection and TypeGen, you must define them using the defineProjection helper from groq.

There are few important things to note here:

  • In the example above, the generated type (e.g., AuthorSummaryProjectionResult) includes a ProjectionBase brand, allowing unions of projection results if a projection applies to multiple document types.
  • TypeGen intelligently removes types from the projection result if all fields in the projection evaluate to null for a given document type.
  • When using Typegen, you cannot pass raw projection strings to useDocumentProjection and get type inference; you must use defineProjection.

GROQ queries

Similarly to useProjection, when using the useQuery hook, you must define your GROQ queries using defineQuery from the groq package to get type inference:

Note that useQuery accepts options as a single object, allowing you to spread handles easily. For example:

Document lists

The App SDK’s document list hooks, useDocuments and usePaginatedDocuments, benefit from TypeGen through dataset scoping (as shown earlier). You can use the documentType option to specify the document type(s) you are querying:

Specific document types

When you know the specific document type you're dealing with, you can make your TypeScript code even more precise using the methods described below.

Parameterizing DocumentHandles

DocumentHandle is a generic type that accept type parameters. You can provide a specific document type literal (like 'book') as a type argument. This is useful for typing props or variables that should only reference a handle for a specific document type:

This works because the full definition of DocumentHandle includes generic type parameters (TDocumentType, TDataset, TProjectId) that default to string but can be made more specific.

Using SanityDocument for document data

If you need the type for the actual document data itself (not just the handle), the groq package exports the SanityDocument<TDocumentType> helper type. Pass the document type literal to get the corresponding generated interface for the document content:

In summary:

  • Use DocumentHandle<'yourType'> to constrain a document handle to documents of a specific type.
  • Use SanityDocument<'yourType'> to type the actual data structure of a document of a specific type.

Workflow considerations

Regeneration

You'll need to re-run npm run typegen whenever you:

  • Change your Sanity schemas.
  • Add or modify queries/projections defined with defineQuery or defineProjection.
  • Consider integrating this into your dev script or a file watcher.

TypeGen is additive

TypeGen is designed to enhance the App SDK experience. If you don't use it, the App SDK hooks will still work, but data types will often default to any or unknown, losing the benefits of TypeScript. Adopting TypeGen later should be a non-breaking change that simply adds type safety.

JavaScript projects

Even if your project doesn't use TypeScript, you can still leverage TypeGen to enhance your JavaScript development experience.

By following the steps in this guide – extracting your schema, installing the necessary packages, using helpers like createDocumentHandle, defineProjection, and defineQuery, and running npm run typegen – you create a sanity.types.ts file.

While your JavaScript code won't undergo compile-time type checking, modern code editors (like VS Code) that use the TypeScript language service can read this generated file.

This often results in significantly better autocompletion within your JavaScript files when interacting with App SDK hooks and data. Remember, however, that using defineProjection and defineQuery is still required for TypeGen to generate types for those specific artifacts.

Was this page helpful?