Skip to content
← Back to blog
Comparison

Sanity vs git-based blog: schema as code isn't PR review

Sanity vs git-based blog: Sanity versions its schema in Git, but published posts skip PR review entirely. What that gap means for a SaaS blog's editorial process.

By Mitrasish, Co-founderJul 30, 202610 min read
Sanity vs git-based blog: schema as code isn't PR review

Sanity's marketing line is "content as code," and half of that claim is true and specific: schema lives in a Git repo, with branches, pull requests, and CI, the same as your application code. The other half is where the claim gets loose. The blog post itself, the words a reader sees, is a JSON document in Sanity's hosted Content Lake, edited live in Studio by whoever has access, published with no diff and no required review step. If your bar for "as code" is that every change gets reviewed like a code change, Sanity's schema clears it and your posts don't. That gap is the whole subject of this post, and it's the same gap our headless CMS vs git-based blog comparison covers at the category level, just narrowed here to the one vendor that leans hardest on the "as code" framing.

Sanity vs git-based blog: the one-line answer

Sanity versions its schema in Git. It does not version its content in Git. A git-based blog versions both the same way, because there's only one repo and one publish event: a merged pull request. If you want every blog post reviewed the way a pull request reviews code, diffed, commented on, approved before it ships, Sanity's architecture doesn't give you that by default, and a git-based blog gives it to you by construction.

That's the practical difference underneath the marketing language. The rest of this post is the mechanics of why.

What Sanity actually versions in Git: the schema, not the post

Sanity's own blog is direct about what "schema as code" means in practice: developers define content models in JavaScript or TypeScript, and those files "give access to versioning, branching, and collaboration workflows" the same way application code does, per Sanity's post on scaling content beyond your frontend. That's a real, useful property. It's also a property of the schema, not of the documents that schema describes.

Schema-as-code is real: JS/TS models, branches, PRs, CI

Open a typical Sanity project's repo and you'll find a schemas folder full of .ts files, a sanity.config.ts, and a Studio configuration, all committed like any other source file. Sanity's own guidance on structuring a code repository recommends a monorepo with a dedicated Studio folder for exactly this, so schemas, plugins, and static config get "version control" the same way the frontend does. Sanity's own course on git-based workflows for a Next.js app walks a developer through branching and pull-requesting that same repo, application code and schema together, before merging to main.

That's genuinely the same discipline your app code gets: a schema change is a diff, someone reviews it, CI can run against it, and a bad field type change gets caught in review instead of in production. This part of the claim holds up.

Content lives in the Content Lake, not the repo

The document a schema describes doesn't live next to it. A Sanity dataset is, in the platform's own words, "a collection of JSON documents" stored in Sanity's hosted infrastructure and queried over HTTP with GROQ or GraphQL, per Sanity's Content Lake documentation. There's no file for a blog post sitting in your repo next to the schema that describes it. It's a record at an API endpoint, one HTTP call away, with zero Git history attached to it.

That's the split worth sitting with. The schema, the shape of a blog post, is code. The blog post itself is data in a separate system with its own lifecycle, its own permissions, and its own publish mechanism that has nothing to do with git merge. Sanity's own remote MCP server, which lets an AI agent run GROQ queries and patch documents directly against a project's Content Lake, is further evidence of where the actual write path lives: an API surface, schema-aware but Git-blind, not a repo. We cover that server's full capability, and the access tradeoffs of connecting an agent to it, in MCP servers for blogs.

Real-time collaborative editing is a feature, and it's also the gap

Sanity Studio's headline editorial feature is real-time multiplayer editing, and it's a genuine strength for the right team. Sanity's own Studio page puts it plainly: "Same document, multiple editors, character-level sync. No locking, no merge conflicts, no 'someone else is editing this.'" Two editors can be in the same post at the same moment, watching each other's cursor, and both sets of changes land without either person blocking the other.

That's a real advantage over a git-based workflow, where two people editing the same Markdown file at once means one of them resolves a merge conflict. For a marketing team with several non-technical writers working the same doc simultaneously, character-level sync beats waiting your turn.

Same document, multiple editors, live sync, no PR in between

Here's the part that should give a SaaS team pause: that same live-sync mechanism is what stands between an editor typing a sentence and that sentence being visible in Studio, immediately, to every other collaborator with access. There's no draft branch to diff against, because there's only one document, mutating in place, mirrored to everyone connected. A pull request needs two states to compare, a before and an after. Real-time collaborative editing, by design, collapses that into one continuously-updating state. The feature that makes Sanity's editor pleasant to use is structurally the same feature that removes the diff a PR review depends on.

Sanity's own "review" state is a custom or plugin workflow, not a diff

Sanity does ship review tooling on top of that live document, just not a Git-style diff. Sanity's own glossary entry on drafts and publishing workflows tells teams to look for "clear content states (Draft, In review, Published), role-based approvals, and shareable previews," per Sanity's glossary on drafts and publishing workflow, which is best-practice guidance, not a description of a single built-in switch every project gets by default. Content Releases extends that further, bundling and scheduling changes with structured approvals and rollback, though that specific feature is an Enterprise-tier capability per Sanity's own pricing page, not something a Free or Growth-plan team gets by default.

What none of that gives you is a diff a reviewer reads before approving. A kanban-style editorial workflow, moving a post from "Draft" to "In review" to "Published" with named stages and assignments, is something teams commonly build themselves or install as a plugin, like the community-maintained Sanity Workflow plugin, rather than something Sanity Studio enforces out of the box. An "In review" label on a document is a status field. A pull request is a diff, a required approval, and a merge gate a repo can be configured to enforce for every single change. Those are different guarantees, and only one of them makes it structurally impossible to publish an unreviewed post.

Why "schema as code" doesn't give you "content as code"

A merged schema PR and a published post are two different events

In a git-based blog, there's one publish event: a merged pull request. The diff that got reviewed is the exact content that goes live, because the build that ships it reads straight from the merged commit. There's no second system, no separate publish action, standing between "a human approved this exact text" and "this exact text is on the internet."

In a Sanity project, there are two separate events that happen to share a vendor. A schema PR gets reviewed and merged into your repo, on its own timeline, by whoever owns the codebase. A document gets edited live in Studio and published, on its own timeline, by whoever has editor access to that dataset. The two events aren't coupled. You can merge a schema change today and have an editor publish a post through that schema next week with zero review, because the schema's review process and the content's publish process were never the same gate to begin with.

What a git-based blog gets by construction that Sanity needs config to approximate

A git-based blog gets three things for free, just from being a repo: every change is a diff, every publish requires a merge, and the merge is the deploy. Getting the same guarantees on Sanity means deliberately building them, a custom document action that blocks the publish button until a reviewer role signs off, a webhook that snapshots the previous version so there's something to diff against, or a plugin that adds the kanban stages Studio doesn't ship natively. None of that is hard, teams do it, but it's configuration you own and maintain, not a property of the platform. Skip that setup and "review" is a status label a writer can move themselves.

Choosing between Sanity and a git-based blog for a SaaS blog

SignalLean toward
Non-technical writers need a visual, real-time collaborative editorSanity
Same content model feeds a website, an app, and emailSanity
Every post should get a required diff-and-approve review, no exceptionsGit-based blog
Small technical team, blog is the only content channelGit-based blog
You're willing to build or install custom approval toolingSanity
The merged pull request should be the only publish eventGit-based blog

Pick Sanity when non-technical editors need real-time collaboration across channels

Sanity earns its complexity when the people writing content aren't developers, when several of them need to work the same document at once without a merge-conflict workflow getting in the way, or when one content model needs to reach a website, a mobile app, and a marketing email from a single schema. Ghost, Contentful, and Sanity together define most of the headless CMS market, where WebTechSurvey tracks Ghost leading with 22,422 live sites and 28.89% share, ahead of Contentful's 14,817 and Sanity's 14,011 tracked domains, a reminder that Sanity is competing in a real, populated category, not carving out a niche. It's also a well-funded one: Sanity has raised roughly $135.7 million across five rounds, including an $85 million Series C in May 2025 led by Bullhound Capital, per Clay's funding dossier, evidence it's a maturing platform investing in exactly this kind of editorial tooling, not a niche side project.

Pick a git-based blog when every post should be reviewed like code

If the honest goal is "every post gets the same review a pull request gives a code change," Sanity's architecture makes you build that gate yourself, and a missed custom action or an editor with the wrong role can still publish straight past it. A git-based blog doesn't need that extra layer, because the repo already enforces it: no merge, no publish. That's the same review-gate argument that matters for AI-assisted writing specifically, where a human checkpoint before publish is the practical answer to whether Google penalizes AI content more than the writing process itself.

Where an AI writer fits either way

An AI writer that drafts inside Sanity Studio is writing into the live document, the same one multiple editors can touch simultaneously, with no PR to route through unless you've built one. An AI writer that drafts into a git-based blog is writing into the one place a diff already exists by default: it opens a branch, proposes a commit, and a human reviews and merges it exactly like a code change, because that's what a git-based blog already requires of every change, human or AI.

That's the model Lyra is built around. She writes into your repo, opens a pull request, and nothing goes live until someone merges it, the same review discipline this whole post has been describing, applied to AI-written drafts specifically instead of bolted on after the fact. She runs on your own Anthropic key at cost, and the plans range from a free tier to cover the first few posts up through Scale for a full content team.

If "every post gets reviewed like a code change" is the bar you actually want, a git-based blog clears it by construction, and that's the exact workflow Lyra writes into.

Try Lyra → · Talk to the founder

FAQ

Frequently asked

Does Sanity use Git for content, or just for schema?+

Just for schema. Sanity's content models, the JavaScript or TypeScript files that define what fields a document type has, live in your repo and can be committed, branched, and reviewed like any other code. The documents themselves, the actual blog posts, live in Sanity's Content Lake, a hosted dataset queried over HTTP with GROQ or GraphQL. Publishing a post never touches Git.

Can you require a pull request before a Sanity post goes live?+

Not by default. Sanity's own guidance recommends clear content states, Draft, In review, and Published, plus role-based approvals, and Content Releases adds scheduled, bundled publishing with rollback on the Enterprise plan. None of that is a diff against the previous version reviewed in a pull request. A hard PR gate on every content change is either a custom document action you build or a community plugin like the Sanity Workflow plugin, not a default behavior.

Is Sanity a good fit for a small SaaS blog?+

It depends on who writes the posts and how many channels the content feeds. Sanity earns its complexity when non-technical editors need a visual, real-time collaborative editor, or when the same content model has to serve a website, an app, and email from one dataset. A small technical team publishing to one blog, where every post should get the same review a code change gets, is better served by a git-based blog where the merged pull request is the only publish event there is.

Built by the tool you're reading about

This post is the kind of thing Lyra ships on her own.

Lyra finds the topics worth ranking for, writes them in your repo's voice, fact-checks every claim, and opens a pull request scored and ready to merge. You review and hit merge. Want to see what she'd write for you? Start free with three posts, no card.

Sanity vs Git-Based BlogSanity CMS Git WorkflowSanity Alternative for Blog SEOGit-Based Blog Schema as CodeSanity Content Lake