Join us live Sept. 27 – How Sanity and Vercel powered Morning Brew's transformation –>

GraphQL Schema

By Espen Hovlandsdal

Declare a Sanity schema using GraphQL SDL syntax



⚠️ This module is no longer maintained!

The type system in Sanity is very expressive. GraphQL directives are neat, but modeling every schema variation through them can be a bit of a hassle. Still - this module/repo serves as an example of the fact that Sanity schemas are "just" javascript - and can be generated using other javascript. Pretty sweet!


Declare a Sanity schema using GraphQL SDL syntax. Try the demo?

  • Auto-infers title from type/field names (leadAsset -> Lead asset)
  • Type names are automatically camelcased (BlogPost -> blogPost)
  • Types that implement "Document" is made into document types
  • Document types as field type assumed to be references, object types as inline
    • Use @inline directive to use document type embedded into parent document
  • Directives for most schema type options
  • "Non null" treated as "required" validation rule (only enforced in Studio)


# In your Sanity studio folder
yarn add sanity-graphql-schema

Basic usage

In your schema entry point (usually schemas/schema.js), you normally have something along the lines of this:

import createSchema from 'part:@sanity/base/schema-creator'
import schemaTypes from 'all:part:@sanity/base/schema-type'

import author from './author'

export default createSchema({
  name: 'default',
  types: schemaTypes.concat([author])

To use this module, import it, call the imported function with a GraphQL schema defined in the GraphQL schema definition language, and replace the value passed to createSchema() with the output:

import createSchema from 'part:@sanity/base/schema-creator'
import {fromGQL, graphql} from 'sanity-graphql-schema'

const schema = graphql`
  type Author implements Document {
    name: String!
    profileImage: Image

  type BlogPost implements Document {
    title: String!
    slug: Slug
    body: Text
    leadImage: CaptionedImage
    tags: [String!]! @display(layout: "tags")
    author: Author!

  type CaptionedImage implements Image {
    caption: String!

export default createSchema({
  name: 'default',
  types: fromGQL(schema)


  • @display(title: String, icon: String, layout: String) Allows you to:
    • Set title of fields and types, overriding the auto-generated title
    • Set layout mode for a field (for instance, set tags as layout for an array field)
    • Set icon for document types by passing an icon ID (see example below)
  • @fieldsets(from: [SanitySchemaFieldSet!]!) Set the fieldsets available for an object/document type. Takes an array of {name, title} pairs

  • @fieldset(set: String!) Assign a field to a given fieldset

  • @orderings(from: [SanitySchemaOrdering!]!) Set the available ordering options for a document type. Takes an array of {name, title, by} pairs - see Sanity documentation for more information

  • @enum(values: [SanityNameTitlePair!]!, layout: String, direction: String) Set on string fields if you only want to allow certain values.
    • values takes an array of {name, title} pairs.
    • layout can be one of dropdown or radio, dropdown being the default.
    • direction determines which way radio buttons flow (horizontal, vertical)
  • @extract(metadata: [String!]!, originalFilename: Boolean) Set on fields of type Image or File to determine which metadata to extract, and whether or not to store the original filename

  • @slug(source: String, maxLength: Int) Set on fields of type Slug, determines which field to generate slugs from, or set maximum length of the slug.

  • @hotspot Set on image fields to opt-in to the hotspot/crop functionality

  • @inline Set on fields that use a document type as it's value if you want to embed the value instead of referencing an existing document

  • @hidden Set on fields to hide them from the user interface, yet still be recognized by the underlying schema machinery

  • @readOnly Set on fields to that should not be editable from the studio


  • [x] Generate GQL types for custom types (color input, for instance)
  • [x] Custom scalars (markdown)
  • [x] Throw on non-reference union fields
  • [x] Better error handling
  • [x] Blocks/spans
  • [ ] Validation directives
  • [ ] Inject icons, input components as options argument
  • [ ] JSON scalar for arbitrary input for custom types? Or options as dotpath? Both?


git clone
cd sanity-graphql-schema
npm install
npm test


MIT © Espen Hovlandsdal

Install command

yarn add sanity-graphql-schema


Other plugins by author

Mux input
- has 6 likes

v3 Ready

Upload videos to Mux directly from the studio.

Go to Mux input

Google Maps input

Official(made by Sanity team)
v3 Ready

Use geo-related input types using Google Maps.

Espen Hovlandsdal
Go to Google Maps input

PortableText to React
- has 10 likes

Official(made by Sanity team)

Render PortableText content in React

Espen Hovlandsdal
Go to PortableText to React


An opinionated, enhanced plugin development experience.

Espen Hovlandsdal
Go to Sanipack