Sanity

Sanity Studio is the open-source, config-driven React framework you customize and deploy as the editing UI for Sanity's real-time content backend.

Framework
npm
v6.12.0
6,312stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
92/100Excellent
Development Activity100
Maintenance96
Community72
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
85/100Excellent
Architecture82
Code Quality88
Innovation78
Learning Curve90

Sanity is the npm package that ships Sanity Studio — an open-source, single-page React application for editing structured content in real time. It bundles the Studio’s core packages (schema builder, form system, structure/desk tooling, presentation and migration APIs) behind one versioned entry point, and its sanity CLI binary scaffolds, develops, builds, and deploys Studio instances that connect to Sanity’s hosted Content Lake.

Rather than a fixed admin panel, the Studio is a customization framework: you define schemas and workspace structure in TypeScript/JavaScript, and Sanity composes the editing UI, validation, and real-time collaboration around that config. Plugins hook into the same defineConfig surface used by first-party features like the Portable Text editor, GROQ-powered search, and Presentation (visual editing).

What You Get

  • A pnpm/turbo monorepo package bundling the Studio’s core UI, schema, structure, presentation, and migration modules behind versioned subpath exports (sanity/desk, sanity/migrate, sanity/cli, sanity/presentation)
  • A sanity CLI binary for scaffolding (npm create sanity@latest), running, building, and deploying Studio instances
  • A plugin architecture built around defineConfig() for composing schema, structure, and custom UI across first- and third-party plugins
  • Built-in GROQ query support, a Portable Text rich-text editor, and asset pipeline integration with Sanity’s Content Lake
  • A Structure Builder for hand-crafting the content navigation tree instead of accepting an auto-generated document list

Common Use Cases

  • Headless CMS for a Next.js/Astro storefront, with schemas defined in Sanity and content queried via GROQ from a separately deployed frontend
  • Custom internal editing tools built with the Structure Builder so editors see a curated navigation rather than a flat document list
  • Multi-language content operations using the Studio’s built-in i18n and internationalized array fields to manage localized content from one workspace
  • Visual, inline editing for marketing sites via the presentation package wired into a frontend so marketers can click into live page elements

Under The Hood

Architecture Sanity Studio’s packages/sanity package is organized as a monorepo workspace exposing multiple subpath entry points (src/_exports/*.ts) that map to independent feature domains under src/core (config, schema, form, studio, i18n, releases, comments, tasks) plus dedicated top-level modules for desk, structure, presentation, router, media-library, and insert-menu. Configuration flows through defineConfig() (src/core/config/defineConfig.ts), which resolves plugin config via resolveConfig.ts/resolveConfigProperty.ts into a single reducer-composed context (configPropertyReducers.ts), consumed by React context providers in _singletons/context. The CLI binary (bin/sanity) is a thin resolver that locates and either imports or spawns the actual @sanity/cli binary, keeping the sanity package itself framework-shaped rather than CLI-shaped. Changing the core config-resolution pipeline would ripple through every plugin and Studio deployment, since plugins, schema, and structure are all merged through that same reducer chain.

Tech Stack The package is written in TypeScript and built with the repo’s turbo-orchestrated pipeline; runtime dependencies span the Sanity ecosystem (@sanity/client, @sanity/cli, @sanity/diff-patch, @sanity/asset-utils, @sanity/comlink) alongside the Portable Text editor stack (@portabletext/editor, @portabletext/react, @portabletext/to-html) and UI primitives (@sanity/ui, @dnd-kit), with react, react-dom, and styled-components as peer dependencies. Content and search integrate with GROQ against Sanity’s hosted Content Lake rather than a local database. Linting runs through oxlint/oxfmt, a Rust-based linter/formatter, tests run on Vitest with coverage, and Playwright drives the e2e suite; the monorepo is managed with pnpm workspaces and Turborepo for task caching across dozens of packages.

Code Quality The package ships an extensive suite of colocated *.test.ts(x) files (hundreds across the source tree, e.g. src/structure/hasObsoleteDraft.test.ts), indicating unit tests are the norm rather than the exception, and CI runs a wide array of dedicated GitHub Actions workflows (e2e, e2e-auth, browser-tests, chromatic visual regression, format checks, bundle-stats), showing testing is enforced rather than optional. TypeScript is used throughout with a shared base tsconfig, and error typing is explicit in places like ConfigResolutionError.ts/ConfigPropertyError.ts rather than relying on generic throws. Naming is domain-scoped and consistent (resolveConfig, resolveConfigProperty, configPropertyReducers), and oxlint runs repo-wide with a dedicated i18n lint plugin enforcing translation-key discipline.

API Design Getting started is a single npm create sanity@latest command that scaffolds a working Studio, and ongoing customization happens through one composable defineConfig() call rather than scattered configuration files, keeping the learning curve front-loaded rather than distributed. Subpath exports (sanity/desk, sanity/structure, sanity/migrate, sanity/presentation, sanity/_internal) are deliberately segmented so consumers only pull in the plugin surface they need, though underscore-prefixed “_internal”/“_singletons” exports signal that part of the public API is still semi-private and subject to change. Documentation is extensive, but the breadth of the config surface (schema, structure, plugins, presentation, i18n, releases) means meaningful customization requires reading well beyond the quickstart.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search