I’m making a spec for design system documentation
Let me get this out of the way–I have no right to be doing this. But I’m doing it anyways. It’s high time for a standard spec for design system documentation. So I’m making one. I call it the Design System Documentation Spec. Because that’s what it is.
A design system’s most valuable asset is its institutional knowledge. It always has been. But that knowledge isn’t treated like it’s valuable. It’s stored on third-party servers, in proprietary formats, or in no format at all. The industry is now finally understanding the value of knowledge management. Not for the right reasons, but I’ll take what I can get.
I’m seizing the moment to pitch this. I want this spec to cover common design system documentation topics. It has to be extensible for the areas it omits. Using the schema has to be straightforward–but not in a dumbed-down kind of way.
A spec like this would solve all sorts of issues design systems teams struggle with. Such as:
- A standard format makes it easier to have a true single source of truth. It could lower the barrier for aggregating documentation from one origin.
- A portable standard means no lock-in. Lock-in sucks. A team’s content is theirs to use, move, and access how they please.
- A portable standard schema makes building custom tools more approachable. Imagine not having to wrestle with data formatting to make a simple plugin…
- Oh, and AI. I’m not going to insult your intelligence and/or bore you with the same old crap. Structured data is useful for AI. You know this. If you don’t, look anywhere else to get a rundown.
Structure
There’s a lot of details, but the meat is in two key sections. The first section is entities. Each entity maps to a common design system part. Components, tokens, patterns, and so on. The entity contains the typical blocks of content to document it. Which leads to the second section…
The second section is document blocks. These are the heart of the spec. Each document block represents a logical chunk of documentation (api, do/don’t, examples, etc.). They are modular and mostly interoperable. For instance, components and tokens use the same guidance schema. The spec allows as many or as few document blocks needed in an entity.
Demo time
I’m keeping this demo focused on a single component. Mainly because I’ve spent the majority of my thinking on the component schema.
It doesn’t take much to define a component in this schema. Below is its simplest form:
{
"$schema": "https://designsystemdocspec.org/v0.1/dsds.bundled.schema.json",
"dsdsVersion": "0.1",
"entity": {
"kind": "component",
"name": "button",
"displayName": "Button",
}
}
Metadata
The metadata section provides a collection of properties to describe the component. This section will be most helpful for discovery and relating one entity to others.
{
"$schema": "https://designsystemdocspec.org/v0.1/dsds.bundled.schema.json",
"dsdsVersion": "0.1",
"entity": {
"kind": "component",
"name": "button",
"displayName": "Button",
"metadata": [
{
"kind": "description",
"value": "Triggers an action when pressed."
},
{
"kind": "status",
"status": "stable"
},
{
"kind": "tags",
"items": ["action", "interactive", "atom"]
},
{
"kind": "links",
"items": [
{
"kind": "documentation",
"url": "https://...", "label":
"Button documentation"
},
{
"kind": "source",
"url": "https://...",
"label": "Git source"
},
{
"kind": "package",
"url": "https://...",
"label": "npm package"
}
]
}
]
}
}
Document blocks
The blocks are where the heavy lifting occurs. All the content people associate with documentation goes here.
{
"$schema": "https://designsystemdocspec.org/v0.1/dsds.bundled.schema.json",
"dsdsVersion": "0.1",
"entity": {
"kind": "component",
"name": "button",
"displayName": "Button",
"metadata": [...],
"documentBlocks": [
{
"kind": "purpose",
"useCases": [
{
"kind": "positive",
"description": "Submitting a form."
},
{
"kind": "negative",
"description": "Toggling a persistent boolean setting.",
"alternative": {
"name": "switch",
"rationale": "Switch communicates an on/off state with accessible role='switch'."
}
}
]
},
{
"kind": "guideline",
"items": [
{
"kind": "required",
"guidance": "Use only one primary button per section.",
"rationale": "Primary buttons should always represent the single most critical action within a logical region. Displaying more than one primary button dilutes focus.",
"category": "development"
},
{
"kind": "prohibited",
"guidance": "Don't use Button for navigation.",
"rationale": "Screen readers announce buttons and links differently. Using a button for navigation confuses keyboard and screen reader users.",
"category": "accessibility"
}
]
},
{
"kind": "api",
"platform": "React",
"properties": [
{
"name": "mode",
"values": [
"primary",
"secondary",
"tertiary"
],
"description": "Sets the importance of the action",
"required": false,
"defaultValue": "default"
},
{
"name": "label",
"type": "String",
"description": "Button text label",
"required": true
},
{
"name": "icon",
"type": "ReactNode",
"description": "Displays a start-aligned icon beside the label",
"required": false
}
],
"events": [
{
"name": "onClick",
"description": "Triggered on click or keyboard press",
"returns": "(event: React.MouseEvent<HTMLButtonElement>) => void"
}
]
},
{
"kind": "variants",
"items": [
{
"kind": "enum",
"name": "mode",
"displayName": "Mode",
"description": "Sets the importance of the button's action",
"values": [
{
"name": "primary",
"displayName": "Primary",
"description": "For tasks of the highest importance."
},
{
"name": "secondary",
"displayName": "Secondary",
"description": "For tasks of normal importance."
},
{
"name": "tertiary",
"displayName": "Tertiary",
"description": "For tasks of low importance."
}
]
}
]
},
]
}
}
Agents
Training for agents is critical, but that information isn’t always relevant to humans. The spec gives space for agent-specific documentation. It does this at both the entity and document block levels.
{
"$schema": "https://designsystemdocspec.org/v0.1/dsds.bundled.schema.json",
"dsdsVersion": "0.1",
"entity": {
"kind": "component",
"name": "button",
"displayName": "Button",
"metadata": [...],
"documentBlocks": [...],
"agents": {
"intent": "Trigger a user-initiated action in the current view without navigating away.",
"constraints": [
{
"level": "must-not",
"rule": "Do not use Button for page navigation — use an anchor element."
},
{
"level": "must",
"rule": "Always set the `type` prop explicitly inside forms."
},
],
"disambiguation": [
{
"entity": "link",
"distinction": "Button triggers an action; link navigates to a URL."
}
],
"antiPatterns": [
{
"description": "Using `icon'` for decorative purposes or to draw attention.",
"instead": "Use `icon` to reinforce meaning only. It should not be used for emphasis."
}
],
"keywords": [
"button",
"action",
"click",
"submit",
"CTA"
]
}
}
}
Yeah, it’s sloppy
Cards on the table–I’ve been using agents to iterate on this spec. I needed to blow through mistakes as quickly as possible–and LLMs have helped. Yes, there’s slop if you look closely. No, it’s not worthy of a decent spec. I didn’t plan to share it early. But other projects are starting to get out there, so this seems like a shit or get off the pot moment.
Every line will be written by a human to hit 1.0, but I’m not precious about what it takes to get there.
I’ve learned a lot
Mainly, that I have a lot to learn. Below are the biggest takeaways.
Markdown ain’t gonna cut it
I think Google’s DESIGN.md is a bad idea. Markdown isn’t structured enough to describe a design system. Not by a long shot. I think this approach locks in workflows that rely on agents. Lock-in sucks.
And I have nothing against those who are all in on AI. This schema is a great source to generate markdown files. I just think a format like this shouldn’t crap the bed if people change their mind.
Maybe I’m naive, but I think we can make a spec that works for people, agents, and old-fashioned scripts. I think a single source of truth has to work for everything/everyone.
Documentation with enough detail is specification
Documentation and specification both work to describe. As this spec grew, their Venn diagram came damn close to a circle. It’s not a perfect overlap, but enough to be intriguing.
This project gets me excited to “work backwards”
I typically write documentation once a thing is code complete. But things change once documentation doubles as specification. I’ve used this format to experiment with a documentation-first approach. The results are promising enough to keep me interested.
I’ve gotten decent Figma and coded components from documentation/agent workflows. Not perfect, or great. But good enough to keep my attention.
Public standards are different than corporate standards
I didn’t see myself making something like this. But I don’t see any efforts that get me excited. I see some coming from larger companies–but, nah. Maybe I’m cynical, but I question the motivations.
I have an idea in my head for how this should work. And I’d like to make that come to life. Ideally, I’d do this with a group of talented folks. And then let it take whatever shape makes sense.
Next steps
Step one is to use this spec for our team’s design system. I won’t know if it’s load-bearing until it bears weight. We’ll no doubt find a lot of dumb mistakes through this process.
Step two is to have peers use the schema on their projects. Hopefully they only have to deal with the spec’s semi-dumb mistakes. This phase will probably expose the spec’s information/workflow gaps.
Step three is to release it for public use. My hope is that the first two steps will make it serviceable. The last step is where the real work begins.
I could sure use some help
I’ve been working on this by myself for the most part. That’s not going to cut it. I welcome the help. Bang on the the documentation, contribute via PR, or just hit me up.