A scaffolder is documentation that runs

Any component that needs six files in five directories will be built wrong by hand eventually. Generating it is cheaper than writing the guide twice.

Priya Raman

Priya Raman

Design Systems Engineer ·

Abstract green gradient suggesting generated structure

Adding a block to a component-driven CMS is never one file. There is a schema, a component, a registration so the renderer can find it, and an entry in whichever arrays decide where an editor may insert it. Miss any one of them and the failure is silent.

The failure modes are all quiet

  1. No schema registration: the type does not exist, and the block cannot be added at all.
  2. No component registration: the block saves fine and renders as nothing on the page.
  3. Not in the insert menu: the component works, but no editor can reach it.

None of these throw. They produce a page that is missing a section nobody can explain.

One command, every file

Shell
<script setup lang="ts">
// Fetched once, at build time, into the prerendered payload.
const { data } = await useSanityContent<BlogIndexQueryResult>(
    blogIndexQuery
)

// Paging and search are derived from it — no second request.
const matching = computed(() =>
    (data.value?.posts ?? []).filter(matchesFilters)
)
</script>

The generator inserts at marker comments ([scaffold:*]) rather than parsing the files it edits, which is why the markers must survive refactors — and it refuses a type name another schema already declares.

It also encodes the boundary

Project work lands under custom/ on purpose. Everything the three project kinds touch lives there, so a starter update can never collide with it — a convention that is much easier to follow when the tool follows it for you.

Developer ExperienceToolingSanity Studio
Priya Raman

Written by

Priya Raman

Design Systems Engineer

Priya works on the seam between design tokens and the components that consume them, and is unreasonably interested in how colour behaves when someone else picks it.