Follow

Unlocking the frontend

Two long essays on why the frontend needs an ecosystem — and what JSON Schema has to do with it

Two essays about the same frustration: we keep rebuilding the same frontend foundations per project, and a component library alone does not fix that.

Part 1 asks what is actually wrong and why a design system by itself is not the answer. Part 2 argues for JSON Schema as the universal layer — and for letting the frontend describe the content model instead of the CMS.


FactDetail
Part 1“So what's wrong?” — silos, reinvention, and why a design system is not an ecosystem
Part 2“Finding universality” — JSON Schema, reversed roles, and how AI fits
Length≈5,200 + ≈6,400 words
Published2024, on the kickstartDS blog

What's in it

Part 1: the missing ecosystem

Classic architectures, the first wave of web ecosystems, and the uncomfortable conclusion that emancipating the frontend takes more than components — there is no frontend ecosystem the way there is a backend one.

Part 2: reverse the roles

Enter JSON Schema, and “a call to reverse roles”: the frontend owns the description of the content, and the CMS configuration is generated from it.

How this relates to AI

If a system can describe itself — components, props, tokens, content shapes — then a CMS and a language model can use that description. The schema layer is what makes the AI angle more than a demo.

In detail

What is actually inside it

Written from the work

Every claim maps to something built: token layers, schema-derived CMS configuration, generated types, the generator/validator split.

Part 2 dates from March 2024

Before the current wave of AI tooling — the argument about structure over prompts has only got easier to make since.

A call, not a pitch

“A call to reverse roles” is addressed to everyone building frontends and CMSes, not to users of one particular framework.

DetailValue
Part 1kickstartds.com/blog/unlocking-the-frontend-pt1
Part 2…-pt2 (5 March 2024)
Themessilos, ecosystems, schema universality, reversed CMS roles, AI

Technical notes

The decisions behind it

What is the core claim of part 2?
That JSON Schema is the closest thing the web has to a universal description of content — so the durable arrangement is: the frontend owns the schema and the CMS (including its configuration) is generated from it. Everything on these coding pages is downstream of that idea.
Why write it as prose?
Because the argument is architectural: it is about who owns the description of a system. That does not fit in a README.

What part 1 actually diagnoses

The architectural argument, and the counter-argument it answers

Part 1 is dated 6 March 2022 (12 min read) and is a genealogy rather than a complaint list. It walks four stages.

1. Bespoke everything. Models, relations, the logic on top of them, the actions triggered on interaction, and finally a frontend built for exactly those circumstances — all interlocked, so “changes of every kind typically being costly as a consequence, leading to everyone trying to over-spec even more… a vicious cycle of ultimately missed expectations.”

2. MVC and shared practice. Symfony for PHP, Rails for Ruby, Express for Node.js, Spring for Java — plus agile processes. Changes became predictable, and that feedback loop converged everyone on shared best practices, shipped as plugins, extensions and addons.

3. CMS as the web's MVC. WordPress, TYPO3 and Drupal added an already established content domain. But every customer still needed fine-tuning, “the frontend still got painstakingly re-implemented with every major overhaul”, and every editor type — news, career, marketing, blog, internal communication — was pushed into the same monolith.

4. Headless and Jamstack. Decoupling frontend from backend (“Jamstack” set against the classic “LAMP” stack) makes the API a shared contract that both sides can test in isolation. Generators (Gatsby, Next.js, 11ty) then let several sources feed one interface: WordPress for long-form content, Storyblok for landing pages, Sanity for structured content, third-party APIs as needed.

Then the turn: “But… where's my frontend ecosystem?” Everything else got re-use, specialization and standardization; the frontend is still assembled per project — a design file on one side, and “data structures that are the result of decisions that were made in your absence” on the other. The same component is also somehow expected to work on the blog, only to “look and behave slightly different”. Camus' Sisyphus is the epigraph for that job.

The design-system objection gets its own chapter — Why just creating a Design System is not the answer, either. A design system is too often treated as “just another added thing on top, that's expected to be delivered, en passant”, when the real requirement is “adjusting the way frontends are architected” and, “in some places inverting the way we work today”. Note what part 1 does not name: there is no JSON Schema here yet, only a call to standardize “the way components can be compared, the way they expect and consume data, and effective ways of mapping between all of those.”

What part 2 proposes — and where it came from

JSON Schema as the neutral layer, and the roles that have to reverse

Part 2 landed two years later, on 5 March 2024 (20 min). Its universal claim is deliberately narrow: every component has an API — “Component Props” in React, Vue and Svelte, “Property Binding” in Angular, “Variables” in Figma, the structure of Frontmatter in an 11ty project. Today that shape is owned either by a backend/API (“leaking a backend view of the world into the implementation”) or by a design prototype (“a too visually reductionist direction”). Either way, you are downstream of it.

The proposal is to stop being downstream: put JSON Schema in as the neutral description layer, and generate the CMS configuration from it instead of mapping the schema to the CMS. Part 2 calls this “a call to reverse roles”. Decoupling the Design System from any one implementation also separates structure and function from implementation, so one design system can back several component libraries, or several CMS integrations.

The lineage is stated too: 20 years of agency work integrating frontend into PHP systems (TYPO3, WordPress) through templating engines like Fluid; Pattern Lab's habit of documenting every component variant as a JSON data.json; the 2021 move from agency to product; and the rewrite that ditched Pattern Lab for Storybook, Handlebars for React (templating only) and ported those data.json files into JSON Schema-backed “component APIs”. The tooling open-sourced alongside the post splits that layer into two output families: TypeScript types, GraphQL fragments and dereferenced schemas for development, and headless-CMS configuration for integration.

2022
Part 1 published
6 March 2022 — diagnosis only; JSON Schema is not named yet.
2024
Part 2 published
5 March 2024 — the proposal, the reverse-roles call and the AI section.
3
CMS targets named in the post
Static CMS, Storyblok, Netlify Create / Stackbit.
7
Conversion targets in kickstartDS/schema today
Storyblok, Static CMS, Stackbit, Hygraph, Uniform, CPort, TypeScript types.

Predicted vs. shipped

The essays checked against the repositories, after 5 March 2024

Did the Web Components switch happen?
Not yet. Part 2 says replacing the React templates with pure Web Components “seems like a pretty sure thing to happen”, citing Declarative Shadow DOM, React 19 finally merging web-component compatibility, and custom-elements-everywhere.com. In the repository's current state the components are still React .tsx templates (ButtonComponent.tsx, ContactComponent.tsx, …) with no custom-elements package. The prediction is unfulfilled, not disproven.
What did the converter tooling actually grow into?
The post names three targets. kickstartDS/schema now ships seven conversions from one JSON Schema base: Storyblok, Static CMS, Stackbit, Hygraph, Uniform, CPort and TypeScript types. They share one reducer pattern — eight type-specific process functions (processObject, processRef, processEnum, …) plugged into a central walker — so a new target is mostly a mapping, not a rewrite.
How is the reversed role enforced at runtime?
Once a converter applies a key-mutating annotation, the CMS field layout no longer matches the schema shape. For the one such annotation today, x-cms-group-inline, @kickstartds/cambria emits a forward lens per component as invertible operations (hoist, rename, remove). The renderer reverses the lens and applies it to the incoming CMS payload to recover the nested shape its TypeScript types expect. Cambria is a real data-migration engine: 10 invertible lens ops, translation of RFC 6902 JSON Patch operations through lenses, and Dijkstra-based path finding between schema versions.
What about the AI section?
No trace of it in the repos. Part 2 points at outlines and at .json (by outlines' authors) for guided generation that follows a JSON Schema, and frames schema docs as “semantic context for the AI model / LLM”. That remains an argument, not shipped code — the concrete artifacts are the CMS annotation vocabulary (x-cms-group-name, x-cms-group-inline, x-cms-order, x-cms-label) and twelve ADRs recording decisions such as re-allocating Storyblok's tab/section primitives and keeping tab keys deterministic (tab-<groupName>) so two converter runs produce identical diffs.
What does the tooling still not do?
It generates CMS configuration but cannot update an existing one: “Add update capabilities to schema tooling” (open since 6 Jan 2025) and “Add option to update existing config in Storyblok” (open since 1 Jul 2025). Also still open: x-cms-hidden and x-cms-preview, naming of nested object arrays in the Storyblok converter, and enum merging for properties below the root level (open since Nov 2023).