
What Is Sanity? A Beginner's Guide to the Headless CMS
Sanity is a headless content management system that stores your content as structured JSON documents in a hosted database called the Content Lake, and gives your editors a customisable editing app called Sanity Studio. You define your content model in code (TypeScript or JavaScript schemas), editors write and publish in the Studio, and your website or app fetches that content through an API using a query language called GROQ. Because Sanity doesn't render pages itself, you can use the same content on a Next.js site, a mobile app, an email template or anywhere else that can make an HTTP request.
If you're coming from WordPress or a page builder, the headless model takes a little adjustment. You get much more control over how content is structured and displayed, but you also take on the job of building the front end. This guide explains what Sanity is made of, how content flows from the Studio to your site, what a schema and a query look like, where Sanity fits well and where it doesn't, and what you need to get started.
What "Headless" Means
A traditional CMS like WordPress bundles three things together: a database, an admin interface and a theme system that renders HTML. A headless CMS removes the last part. It stores and manages content, then hands it over through an API, and you decide how and where it's displayed.
| Traditional CMS | Headless CMS (Sanity) | |
|---|---|---|
| Content storage | Database on your server | Hosted API |
| Editing interface | Built-in admin | Separate app (Sanity Studio) |
| Front end | Themes and templates | Anything you build |
| Output | HTML pages | JSON over HTTP |
| Hosting | You host the whole stack | Sanity hosts the content, you host the site |
The benefit is separation. Your content isn't tied to one website's templates, so a product description written once can appear on your site, in your app and in a partner feed. If you're curious how WordPress can be used the same way, the post on headless WordPress covers that approach.
The Three Main Parts of Sanity
Sanity has a lot of products and features, but as a beginner you only need to understand three pieces.
Sanity Studio
Sanity Studio is the editing interface. It's an open-source, single-page React application that you configure in a file called sanity.config.ts. The Studio reads your schemas and generates forms for them, so if you define a post with a title, slug, author and body, editors get exactly those fields.
Because it's just a React app, you can customise almost everything: the navigation, field inputs, document previews and the actions available on each document. You can run it locally, deploy it to a free *.sanity.studio URL, or embed it in your own app. The Sanity Studio walkthrough explains each part of the interface.
The Content Lake
The Content Lake is Sanity's hosted, real-time database. Everything editors create in the Studio is saved there as JSON documents, grouped into datasets such as production and staging. You don't install or manage it. You read and write to it through Sanity's APIs, and a CDN-backed endpoint serves cached responses for public queries.
Every document has system fields like _id, _type, _createdAt and _updatedAt, and unpublished changes are stored as separate draft documents. The Content Lake explained post goes deeper into how documents, drafts and perspectives work.
GROQ
GROQ (Graph-Relational Object Queries) is Sanity's query language. It lets you filter documents, follow references and reshape the response in a single request. A query for the five latest posts with their author's name looks like this:
*[_type == "post" && defined(slug.current)] | order(publishedAt desc)[0...5]{
title,
"slug": slug.current,
publishedAt,
"author": author->name
}
The -> operator follows a reference to the author document and pulls in its name, so you don't need a second request. Sanity also offers a GraphQL API if your team prefers it, but GROQ is the default and the one most documentation uses. See what is GROQ for a full introduction.
How Content Flows Through Sanity
Here's what happens from the moment an editor starts typing to the moment a visitor sees the page:
- You define a schema in code, for example a
postdocument type with fields. - The Studio builds a form from that schema, and editors fill it in.
- Edits are saved as a draft in the Content Lake in real time. Other editors see changes live.
- An editor publishes, which copies the draft into the published document.
- Your front end queries the Content Lake with GROQ, through
@sanity/clientor a framework toolkit likenext-sanity. - Your site renders the JSON into HTML, then rebuilds or revalidates when content changes, often triggered by a webhook.
Each step is independent. You can change your front end framework without touching content, or restructure your Studio without redeploying your site.
What a Sanity Schema Looks Like
Schemas are plain TypeScript objects built with helper functions from the sanity package. Here's a simple blog post type:
// schemaTypes/post.ts
import { defineField, defineType } from 'sanity'
export const post = defineType({
name: 'post',
title: 'Post',
type: 'document',
fields: [
defineField({
name: 'title',
type: 'string',
validation: (rule) => rule.required(),
}),
defineField({
name: 'slug',
type: 'slug',
options: { source: 'title' },
}),
defineField({
name: 'publishedAt',
type: 'datetime',
}),
defineField({
name: 'author',
type: 'reference',
to: [{ type: 'author' }],
}),
defineField({
name: 'body',
type: 'array',
of: [{ type: 'block' }],
}),
],
})
Register it in your Studio config and the form appears immediately:
// sanity.config.ts
import { defineConfig } from 'sanity'
import { structureTool } from 'sanity/structure'
import { visionTool } from '@sanity/vision'
import { post } from './schemaTypes/post'
import { author } from './schemaTypes/author'
export default defineConfig({
name: 'default',
title: 'My Blog',
projectId: 'your-project-id',
dataset: 'production',
plugins: [structureTool(), visionTool()],
schema: {
types: [post, author],
},
})
The body field uses the block type, which stores rich text as Portable Text, a JSON format rather than HTML. That makes it easy to render the same content in React, a mobile app or plain text. The post on what is Portable Text explains why that matters, and your first schema walks through building one step by step.
Fetching Sanity Content in Your Front End
On the front end, you create a client and run GROQ queries. In a Next.js App Router project, the next-sanity package wraps @sanity/client with helpers for caching and previews:
// src/sanity/client.ts
import { createClient } from 'next-sanity'
export const client = createClient({
projectId: 'your-project-id',
dataset: 'production',
apiVersion: '2026-10-01',
useCdn: true,
})
// src/app/blog/page.tsx
import Link from 'next/link'
import { client } from '@/sanity/client'
const POSTS_QUERY = `*[_type == "post" && defined(slug.current)] | order(publishedAt desc){
_id, title, "slug": slug.current
}`
export default async function BlogPage() {
const posts = await client.fetch(POSTS_QUERY)
return (
<ul>
{posts.map((post: { _id: string; title: string; slug: string }) => (
<li key={post._id}>
<Link href={`/blog/${post.slug}`}>{post.title}</Link>
</li>
))}
</ul>
)
}
The apiVersion is a date string that pins the API behaviour your code expects, so future changes don't break you. Setting useCdn: true sends queries to the cached API CDN, which is faster and cheaper for public content.
What Makes Sanity Different
Plenty of headless CMSs exist. These are the traits that set Sanity apart:
- Schemas live in code: your content model is version-controlled alongside your app, reviewed in pull requests and deployed like any other code.
- A customisable editor: the Studio is React, so you can add custom inputs, previews, tools and document actions without waiting for a vendor feature.
- Real-time collaboration: several people can edit the same document at once, with presence indicators and live updates.
- Structured rich text: Portable Text keeps formatting as data, so you aren't stuck parsing HTML later.
- Powerful querying: GROQ can join, filter and reshape in one request, which keeps front-end code simple.
- Image pipeline: uploaded images can be resized, cropped and converted on the fly through URL parameters, with editor-defined hotspots. See Sanity images.
- Generous free tier: you can build real projects without paying. The Sanity pricing guide breaks down what each plan includes.
For a fuller tour of these features from a developer's point of view, read why developers love Sanity.
When Sanity Is a Good Fit
Sanity works best when:
- You have a developer (or are one) who's comfortable with JavaScript and a modern framework.
- Content is reused across several channels, such as a website, an app and newsletters.
- Your content is structured, like products, events, recipes or documentation, rather than free-form pages.
- Editors need a tailored workflow, such as custom fields, previews or approval steps.
- You want a fast, static or edge-rendered front end using Next.js, Astro, Nuxt or similar.
When Sanity Might Not Be Right
It's also worth being honest about the trade-offs:
- No front end out of the box: there's no theme you can install and switch on. Someone has to build and host the website.
- A learning curve: schemas, GROQ and Portable Text are new concepts if you've only used WordPress.
- Usage-based limits: plans include quotas for documents, API requests and bandwidth. Busy sites need to watch these and use the CDN.
- Non-technical site owners who want to change layouts themselves may prefer a traditional CMS or a page builder, unless a developer sets up a page-building schema for them.
If you're weighing it against the most common alternative, Sanity vs WordPress compares the two in detail.
How to Get Started with Sanity
Getting a Studio running takes a few minutes. You'll need Node.js 22.12 or later, then run:
npm create sanity@latest
The CLI asks you to log in or create a free account, name your project, create a dataset and pick a template. Then start the Studio locally:
cd my-sanity-project
npm run dev
The Studio opens at http://localhost:3333. From there you can add schemas, create content and test queries in the Vision tool. The step-by-step guide to setting up your first Sanity project covers every prompt and option.
FAQ: What Is Sanity
Yes. Sanity has a free plan that includes the Studio, the Content Lake, public datasets and monthly quotas for documents, API requests and bandwidth. Paid plans add private datasets, more roles, collaboration features and the ability to pay for extra usage.
Sanity Studio is open source and available on GitHub, so you can read, fork and extend it. The Content Lake, where content is stored, is a hosted service run by Sanity and isn't something you can self-host.
Editors don't. Once a developer has set up the schemas and Studio, writing and publishing content is done through a normal web interface. Setting up a project, defining schemas and building the website does require JavaScript or TypeScript knowledge.
Any framework that can make HTTP requests works. Sanity provides official toolkits and guides for Next.js, Astro, Nuxt and React Router, and the JavaScript client works in Node.js, browsers and edge runtimes. You can also call the HTTP API from any other language.
Content is stored in the Content Lake, Sanity's hosted database, inside one or more datasets per project. You access it through APIs and can export a dataset with the CLI at any time if you want a backup or plan to move elsewhere.
It can be, especially if you want a fast custom front end and structured content. If you want a blog running today without writing code, a traditional CMS is quicker to launch, but Sanity gives you more flexibility as the site grows.
Conclusion
Sanity is a headless CMS built around three ideas: content modelled in code, edited in a customisable React Studio and stored as structured JSON in the hosted Content Lake. Your front end pulls exactly what it needs with GROQ, which keeps content independent of any single website or framework.
It isn't the quickest route to a simple brochure site, but it's a strong choice when content needs to be reused, structured carefully or edited through a workflow that fits your team. The best way to understand it is to try it: create a free project, add a schema and run your first query.


