Skip to content

somerandomdude/design-system-documentation-schema

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Design System Documentation Standard (DSDS)

A standard, machine-readable format for design system documentation.


What is DSDS?

DSDS defines a JSON-based format for documenting the six entity types of a design system:

  • Components — Anatomy, API, variants, states, design specifications, best practices, accessibility, content
  • Tokens — Semantic meaning, platform mappings, contrast ratios, usage rules
  • Token Groups — Hierarchical organization of tokens into families and sub-families
  • Themes — Named sets of token value overrides for color modes, density, brand variants
  • Styles — Foundations for color, typography, spacing, elevation, motion, and content — with principles, scales, motion definitions, and best practices
  • Patterns — Broad interaction patterns like navigation, error messaging, and empty states — with anatomy, variants, states, interactions, and content

All structured documentation — guidelines, anatomy, API specs, variants, states, accessibility, examples, design specifications, principles, scales, motion definitions, content, and interactions — lives in a unified document block system. Each document block entry is a typed container identified by a kind discriminator.

The goal is simple: make design system documentation structured, portable, and consumable by tools — whether that tool is a documentation site, a linter, a code assistant, or a human reading JSON.

Why?

Design system documentation today is trapped in tools. It lives in Notion, Storybook, Zeroheight, Confluence, or custom-built sites — each with its own structure, its own conventions, and no interoperability between them.

This creates real problems:

  • Migration is expensive. Switching documentation tools means restructuring everything from scratch.
  • Consistency is accidental. Without a shared structure, every team invents its own format. Consumers must relearn what to expect every time.
  • Tooling can't help. Tools can't reliably consume documentation from other tools because there's no shared schema to build against.
  • AI needs structure. LLMs and code assistants work dramatically better with structured, predictable documentation than with ad hoc prose.

DSDS addresses these problems by defining a standard format that is:

Quality What it means
Structured Every section has a defined shape. Consumers know what to expect.
Machine-readable Tools can parse, generate, validate, and transform documentation.
Portable Documentation is decoupled from any specific tool or platform.
Extensible Vendor metadata can be added without breaking interoperability.
Complementary Works alongside the W3C Design Tokens Format, not against it.

Relationship to W3C Design Tokens

The W3C Design Tokens Community Group defines a format for exchanging token values between tools. DSDS defines a format for exchanging the documentation that describes how those tokens — and the components, styles, and patterns that use them — should be understood and applied.

The two formats are designed to work together. DSDS does not duplicate token values or platform identifiers. The W3C Design Tokens Format file is the source of truth for values. Use the source property on a token entity to link it back to its DTCG definition.

Project Structure

spec/
├── dsds-spec.md                                        # Complete specification (single source of truth)
├── schema/
│   ├── dsds.schema.json                                # Root JSON Schema
│   ├── dsds.bundled.schema.json                        # Auto-generated single-file bundle
│   ├── common/                                         # Shared primitives
│   │   ├── example.schema.json                         # example
│   │   ├── extensions.schema.json                      # $extensions
│   │   ├── link.schema.json                            # link
│   │   ├── system-metadata.schema.json                 # systemMetadata
│   │   ├── rich-text.schema.json                       # richText
│   │   ├── presentation.schema.json                    # presentationImage, presentationVideo, presentationCode, presentationUrl
│   │   ├── status.schema.json                          # status, statusObject, statusValue, platformStatus
│   │   └── purpose.schema.json                         # purpose, useCase
│   ├── entities/                                       # Entity types
│   │   ├── component.schema.json                       # component
│   │   ├── pattern.schema.json                         # pattern
│   │   ├── style.schema.json                           # style
│   │   ├── theme.schema.json                           # theme, tokenOverride
│   │   └── token.schema.json                           # token, tokenGroup
│   └── document-blocks/                                 # Document block types
│       ├── document-blocks.schema.json                  # Scoped unions (componentDocumentBlock, styleDocumentBlock, etc.)
│       ├── accessibility.schema.json                   # accessibility, keyboardInteraction, ariaAttribute, colorContrast
│       ├── anatomy.schema.json                         # anatomy, anatomyEntry
│       ├── api.schema.json                             # api, apiProperty, apiEvent, apiSlot, etc.
│       ├── guideline.schema.json                       # guideline, guidelineEntry
│       ├── content.schema.json                         # content, contentLabelEntry, localizationEntry
│       ├── design-specifications.schema.json           # designSpecifications, spacingSpec, sizingSpec, typographySpec, etc.
│       ├── interaction.schema.json                     # interactions, interactionEntry
│       ├── motion.schema.json                          # motion, motionEntry, motionDuration
│       ├── principle.schema.json                       # principles, principleEntry
│       ├── scale.schema.json                           # scale, scaleStep
│       ├── state.schema.json                           # states, stateEntry
│       └── variant.schema.json                         # variants, flagVariant, enumVariant, variantValue
└── examples/
    ├── starter-kit.dsds.json                           # Complete document with components, tokens, styles, patterns
    ├── minimal/                                        # Lightweight examples showing the floor of documentation
    ├── common/                                         # Per-definition examples for common primitives
    ├── entities/                                       # Per-definition examples for entity types (incl. empty-state pattern)
    └── document-blocks/                                 # Per-definition examples for document block types (incl. motion, content)

scripts/
├── bundle.js                                           # Generates dsds.bundled.schema.json from split schemas
├── validate.js                                         # Validates all example files against the bundled schema
├── sync-examples.js                                    # Syncs markdown dsds:include directives with example JSON
├── build-site.js                                       # Generates the static specification site
├── build-samples.js                                    # Generates the interactive sample viewer from example JSON
├── build-quickstart.js                                 # Generates the quick start guide from minimal examples
└── visualize.js                                        # Generates schema architecture diagram (SVG + Mermaid)

site/
├── tokens.css                                          # Centralized design tokens (colors, fonts, spacing, radii, etc.)
├── style.css                                           # Core site stylesheet (layout, nav, typography — imports tokens.css)
├── pages.css                                           # Shared styles for standalone pages (samples, quickstart)
├── components/                                         # Reusable HTML web components (ES modules)
│   ├── index.js                                        # Barrel file — imports all components, registers custom elements
│   ├── _shared.js                                      # Shared utilities (createShadow, esc, BASE_RESET, FONT)
│   ├── badge.js                                        # <ds-badge> — status/category badges
│   ├── back-to-top.js                                  # <ds-back-to-top> — scroll-to-top link
│   ├── button.js                                       # <ds-button> — button with variants and sizes
│   ├── card.js                                         # <ds-card> — bordered content card
│   ├── code.js                                         # <ds-code> — syntax-highlighted code (block + inline)
│   ├── cross-refs.js                                   # <ds-cross-refs> — cross-reference links
│   ├── def-example.js                                  # <ds-def-example> — definition example block
│   ├── def-index.js                                    # <ds-def-index> — page-level definition index
│   ├── def-section.js                                  # <ds-def-section> — definition section container
│   ├── footer.js                                       # <ds-footer> — page footer
│   ├── heading.js                                      # <ds-heading> — section heading (h1–h6) with anchor
│   ├── note.js                                         # <ds-note> — callout/warning box
│   ├── prop-table.js                                   # <ds-prop-table> + <ds-prop> — schema property table
│   ├── schema-header.js                                # <ds-schema-header> — schema page header
│   ├── scrollspy.js                                    # <ds-scrollspy> — scroll position tracker
│   ├── sidebar.js                                      # <ds-sidebar> — collapsible sidebar panel
│   ├── sidenav.js                                      # <ds-sidenav> + <ds-nav-group> + <ds-nav-link>
│   ├── table.js                                        # <ds-table> — styled table wrapper
│   ├── tabs.js                                         # <ds-tabs> + <ds-tab> — tabbed content
│   ├── toc.js                                          # <ds-toc> — auto-built table of contents
│   ├── toolbar.js                                      # <ds-toolbar> — sticky top toolbar
│   └── type-ref.js                                     # <ds-type-ref> — type reference link
├── samples-template.html                               # Template for the interactive sample viewer
└── dist/                                               # Generated HTML site (auto-generated)

Quick Start

1. Read the spec

Start with spec/dsds-spec.md — it is the single source of truth for the entire specification, covering document structure, entity types, all guideline types, links, status, rich text, use cases, extensions, and naming conventions.

2. Look at the examples

The spec/examples/ directory contains validated example files:

  • starter-kit.dsds.json — A complete document with components, tokens, a style, and a pattern, showing the full architecture.
  • minimal/ — Lightweight examples (8–30 lines each) showing the floor of documentation for each entity type.
  • entities/component.json — A full Button component with anatomy, API, variants (flag and enum types), states, design specs, best practices, purpose, and accessibility.
  • entities/empty-state-pattern.json — An Empty State pattern demonstrating anatomy, variants, states, interactions, content guidelines, and localization on a pattern entity.
  • entities/style.json — A Spacing style with principles, scale, motion definitions, and best practices.
  • entities/token.json — A semantic color token with source reference, category, and guidelines.
  • entities/token-group.json — A hierarchical color palette with nested hue families and grade scales.
  • entities/theme.json — A dark mode theme with token overrides, purpose, best practices, and accessibility.
  • entities/pattern.json — An error messaging pattern with interactions, component references, and accessibility.

3. Validate your documents

Install dependencies and run the validation suite:

npm install
npm run validate

This runs three steps automatically: syncs example includes, bundles the schema, and validates all example files.

To validate your own DSDS file:

npx ajv validate -s spec/schema/dsds.bundled.schema.json -d my-system.dsds.json

Reference the schema in your DSDS files for editor support:

{
  "$schema": "./spec/schema/dsds.schema.json",
  "dsdsVersion": "0.1",
  "documentation": [
    {
      "name": "My Design System",
      "components": [
        {
          "kind": "component",
          "name": "my-component",
          "displayName": "My Component",
          "description": "A brief description.",
          "status": { "status": "draft" }
        }
      ]
    }
  ]
}

4. Build the spec site

npm run build
# Open site/dist/index.html

The site is auto-generated from the schema JSON files — property tables, type descriptions, and cross-references are all derived directly from the schemas. The prose modules provide context and examples.

5. Regenerate the bundled schema

After changing any schema file, regenerate the bundled version:

npm run bundle

6. Visualize the schema architecture

Generate a diagram showing how all schema files relate to each other:

npm run visualize

This produces:

  • site/dist/schema-architecture.mmd — Mermaid source (renders natively on GitHub)
  • site/dist/schema-architecture.svg — Clean SVG with no CSS, compatible with Figma

Options:

node scripts/visualize.js --format=svg               # SVG only
node scripts/visualize.js --format=mmd               # Mermaid source only
node scripts/visualize.js --layout=root,entities,guidelines,common  # Custom column order
node scripts/visualize.js --layout=root+common,entities,guidelines  # Stack groups with +
node scripts/visualize.js --no-edges                  # Hide dependency edges

7. Build the interactive sample viewer

Generate a side-by-side documentation page that shows how DSDS JSON maps to rendered output:

npm run build-samples

This reads example JSON files from spec/examples/ and produces site/dist/samples.html — a self-contained page with:

  • Tabs for each entity type: Button Component, Color Token, Error Messaging Pattern, Spacing Style, Dark Theme
  • Side-by-side layout: raw JSON on the left, rendered documentation on the right
  • Element-level highlighting: hover over any rendered element to see its corresponding JSON, and vice versa
  • Color-coded section bars mapping JSON sections to their visual output
  • Off-screen indicators when highlighted code is scrolled out of view

To add a new example tab, add an entry to the SAMPLES array in scripts/build-samples.js:

{
  file: "entities/component.json",  // path relative to spec/examples/
  key: "component",                 // top-level key to extract
  id: "component",                  // unique tab identifier
  label: "Button Component",        // human-readable tab label
}

8. Build the quick start guide

Generate a concise, standalone introduction to DSDS from the minimal example files:

npm run build-quickstart

This reads spec/examples/minimal/ and produces site/dist/quickstart.html — a single-page guide covering:

  • Document structuredsdsVersion, documentation groups, and the items array
  • Entity types — all six kinds with descriptions and common properties
  • Guidelines system — the 13 guideline types, which entities support them, and how purpose and best-practices work
  • Minimal examples — copy-pasteable starting points for every entity type, pulled live from the validated examples
  • Validation — how to use the JSON Schema and CLI to validate your documents

The examples are read from disk at build time, so the guide automatically reflects any changes to spec/examples/minimal/.

Document Structure

A DSDS file has a dsdsVersion and a documentation array. Each entry in documentation is a named group with separate typed arrays for each entity kind: components, tokenGroups, themes, styles, patterns. All arrays are optional.

Three optional top-level properties describe the design system as a whole:

extends (optional) — declares that this document extends another DSDS document — typically a core design system. Identifies the base system by name, optional URL, and optional version. See Systems of Systems: Extends.

purpose (optional) — describes what the design system is for, who it serves, and when teams should or should not adopt it. Contains a description and an array of useCases with positive and negative scenarios.

bestPractices (optional) — system-level best practices that apply across the entire design system. These are cross-cutting rules like "always use semantic tokens" or "test all components at 200% zoom" — not component-specific guidance (which lives in each entity's documentBlocks array). Each entry pairs an actionable guidance statement with a rationale and an enforcement kind.

System-level vs. entity-level: The root purpose and bestPractices apply to the design system as a whole. They are distinct from the entity-level purpose and guideline document block types that appear inside each entity's documentBlocks array.

{
  "dsdsVersion": "0.1",
  "purpose": {
    "description": "A unified component library for all Acme product teams.",
    "useCases": [
      { "description": "Building new product UIs on the Acme platform.", "kind": "positive" },
      {
        "description": "One-off marketing landing pages with heavy custom art direction.",
        "kind": "negative",
        "alternative": {
          "name": "marketing-toolkit",
          "rationale": "The marketing toolkit provides art-direction-first primitives."
        }
      }
    ]
  },
  "bestPractices": [
    {
      "guidance": "Always use semantic tokens instead of raw color values.",
      "rationale": "Semantic tokens ensure themes apply correctly across all surfaces.",
      "kind": "required",
      "category": "development"
    },
    {
      "guidance": "Test all components at 200% browser zoom.",
      "rationale": "WCAG 1.4.4 requires content to be functional at 200% zoom.",
      "kind": "required",
      "category": "accessibility",
      "criteria": [
        { "url": "https://www.w3.org/TR/WCAG22/#resize-text", "label": "1.4.4 Resize Text" }
      ]
    },
    {
      "guidance": "Do not override token values at the component level.",
      "rationale": "Overrides break theme consistency and make audits unreliable.",
      "kind": "prohibited",
      "category": "development"
    }
  ],
  "documentation": [
    {
      "name": "Acme Design System",
      "components": [
        { "kind": "component", "name": "button", "..." }
      ],
      "tokenGroups": [
        { "kind": "token-group", "name": "color-palette", "..." }
      ],
      "themes": [
        { "kind": "theme", "name": "dark", "..." }
      ],
      "styles": [
        { "kind": "style", "name": "spacing", "..." }
      ],
      "patterns": [
        { "kind": "pattern", "name": "error-messaging", "..." }
      ]
    }
  ]
}

Entity Types

Each entity kind lives in its own named array within a documentation group. The array name is the primary type indicator. Every entity still carries a kind discriminator for use in contexts where the source array is not available, along with common identity properties (name, displayName, description, status) and a documentBlocks array for all structured documentation.

kind value Entity Array Description
"component" Component components A reusable UI component
"token" Token (inline in token groups) A single design token
"token-group" Token Group tokenGroups A hierarchical group of related tokens (recursive)
"theme" Theme themes A named set of token overrides (lists token names, not values)
"style" Style styles A macro-level visual style
"pattern" Pattern patterns A broad interaction pattern

The agents property

Every entity accepts an optional agents object providing context optimized for AI/LLM consumption. Human-readable content like documentBlocks is written for people; agents is written for machines.

Property Type Description
intent string One sentence stating the primary purpose.
constraints array Hard rules with must/must-not/should/should-not levels. Each entry has rule, level, and optional context.
disambiguation array Confusion-resolution entries against similar entities. Each has entity (name) and distinction (the deciding criterion).
antiPatterns array Known incorrect uses with corrective alternatives. Each has description and instead.
examples array Ready-to-use code examples. Each has description, code, and optional language.
keywords string[] Semantic retrieval terms and synonyms.
{
  "agents": {
    "intent": "Trigger a user action within the current view.",
    "constraints": [
      { "rule": "Do not use for page navigation.", "level": "must-not" }
    ],
    "disambiguation": [
      { "entity": "link", "distinction": "Use button for actions; use link for navigation." }
    ],
    "keywords": ["action", "submit", "click", "CTA"]
  }
}

Document blocks also accept the same optional agents object. Block-level agent context is scoped to that specific section — for example, an anatomy block's agents might disambiguate part naming, while a guidelines block's agents might provide enforcement-level constraints for AI code generation:

{
  "documentBlocks": [
    {
      "kind": "guideline",
      "items": ["..."],
      "agents": {
        "intent": "Enforce correct Button usage in generated UI code.",
        "constraints": [
          { "rule": "Never place two primary buttons on the same surface.", "level": "must-not" }
        ],
        "keywords": ["button rules", "best practices", "usage guidelines"]
      }
    }
  ]
}

Status

Every entity carries a status property that accepts either a plain string for the common case or a full object when platform-specific tracking is needed:

{ "status": "stable" }

When per-platform readiness is needed, use the object form with overall and platforms:

{
  "status": {
    "overall": "stable",
    "platforms": {
      "react": { "status": "stable", "since": "1.0.0" },
      "ios": { "status": "experimental", "since": "3.0.0" },
      "figma": { "status": "stable", "since": "1.0.0" }
    }
  }
}

The object form requires platforms — if you don't need platform-specific tracking, use the string form. When overall is "deprecated", a deprecationNotice is required.

Document Block System

All structured documentation lives in the documentBlocks array on each entity. Each document block entry is a typed container with a kind discriminator. Entity types accept only the document block types relevant to them through scoped unions:

Scope Used by Specific types General types (all entities)
Component component anatomy, api, events, variants, states, design-specifications guideline, purpose, accessibility, content
Style style principles, scale, motion (same)
Pattern pattern interactions, events, anatomy, variants, states (same)
Token token, token-group, theme (none) (same)

Document Block Types

Kind value Container Items Description
"guideline" items guidelineEntry Actionable usage rules with rationale and enforcement levels
"purpose" useCases useCase When to use and when not to use the entity
"accessibility" Named arrays various Keyboard, ARIA, screen reader, contrast, motion specs
"content" labels, localization contentLabelEntry, localizationEntry Content guidelines and i18n considerations
"anatomy" parts anatomyEntry Component visual structure with token references
"api" Named arrays various Props, events, slots, CSS hooks, methods
"events" items eventEntry Component events with payloads, DOM behavior, and lifecycle
"variants" items flagVariant | enumVariant Dimensions of visual/behavioral variation
"states" items stateEntry Interactive states with token overrides
"design-specifications" properties + variants / sizes / states various Design properties, spacing, sizing, typography, responsive — grouped by variant, size, and state
"principles" items principleEntry High-level guiding beliefs
"scale" steps scaleStep Ordered token value progressions
"motion" items motionEntry Named easing curves with durations and usage
"interactions" items interactionEntry Pattern flow steps

Every document block type accepts an optional agents property — the same agents object available on entities. Block-level agents provide context scoped to that specific documentation section (e.g., constraints specific to accessibility requirements, or disambiguation relevant only to the API surface).

Naming Convention

Document block types follow two naming patterns:

  • Plural names for homogeneous lists: "variants", "states", "principles", "interactions"
  • Singular names for self-contained structures: "guideline", "scale", "anatomy", "api", "accessibility", "design-specifications", "purpose", "content", "motion"

Purpose tells you when. Guidelines tell you how.

DSDS separates two kinds of guidance:

  • Purpose provides concrete scenarios for when to use and when not to use an entity. Each use case carries a kind ("positive" or "negative") and negative entries recommend an alternative with a rationale.
  • Guidelines provide concrete rules for using an entity correctly after you've chosen it. Each rule pairs an actionable guidance statement with a rationale explaining why.
{
  "documentBlocks": [
    {
      "kind": "purpose",
      "useCases": [
        {
          "description": "When the user needs to trigger an action such as submitting a form.",
          "kind": "positive"
        },
        {
          "description": "When the action navigates to a different page.",
          "kind": "negative",
          "alternative": {
            "name": "link",
            "rationale": "Links carry native navigation semantics."
          }
        }
      ]
    },
    {
      "kind": "guideline",
      "items": [
        {
          "guidance": "Limit each surface to one primary button.",
          "rationale": "Multiple primary buttons dilute visual hierarchy.",
          "kind": "required",
          "category": "visual-design"
        }
      ]
    }
  ]
}

Guideline Enforcement Levels

The kind property on each guideline entry classifies how strictly it should be followed. Defaults to "informational" when omitted.

Value RFC 2119 Meaning
"required" MUST Non-compliance is a defect.
"encouraged" SHOULD Follow in most cases; exceptions need justification.
"informational" MAY Advisory context with no enforcement. (default)
"discouraged" SHOULD NOT Avoid unless justified.
"prohibited" MUST NOT Violations are defects.

Guidelines Link to External Criteria

Any guideline can reference external standards via the criteria property:

{
  "guidance": "Button label text must meet a minimum 4.5:1 contrast ratio.",
  "rationale": "Text contrast ensures readability for users with low vision.",
  "kind": "required",
  "category": "accessibility",
  "criteria": [
    {
      "url": "https://www.w3.org/TR/WCAG22/#contrast-minimum",
      "label": "1.4.3 Contrast (Minimum)"
    }
  ]
}

Variants Use Flag and Enum Types

Component variants are modeled as dimensions of variation inside a "variants" guideline. Each dimension is either a flag (a boolean toggle that is on or off) or an enum (a set of mutually exclusive values):

{
  "kind": "variants",
  "items": [
    {
      "kind": "enum",
      "name": "emphasis",
      "displayName": "Emphasis",
      "description": "Controls the visual weight of the button.",
      "values": [
        { "name": "primary", "description": "High-emphasis — the main action." },
        { "name": "secondary", "description": "Medium-emphasis — important but not primary." },
        { "name": "ghost", "description": "Low-emphasis — tertiary actions." }
      ]
    },
    {
      "kind": "flag",
      "name": "full-width",
      "displayName": "Full Width",
      "description": "Stretches the button to fill its container.",
      "purpose": "Provides a prominent call to action in narrow or single-column layouts."
    }
  ]
}

An enum variant (type: "enum") has a values array with at least two entries — use it for dimensions like size (sm/md/lg) or emphasis (primary/secondary/ghost). A flag variant (type: "flag") has no values array — the component either has the flag active or it doesn't. Use it for binary capabilities like disabled, full-width, or icon-only. Both types accept an optional purpose field explaining why the variation exists.

Examples Use Presentations

Every example requires a presentation or a value (or both). Presentations are visual or interactive demonstrations. Four media types are supported:

type What it shows
"image" Screenshot, diagram, annotated mockup
"video" Screen recording, animation, walkthrough
"code" Source code snippet with language metadata
"url" Link to any web resource (Storybook, CodeSandbox, etc.)
{
  "type": "examples",
  "items": [
    {
      "title": "Primary button in default state",
      "presentation": {
        "kind": "image",
        "url": "https://design.acme.com/assets/button-primary.png",
        "alt": "A primary button with a blue background and white label text 'Save'."
      }
    }
  ]
}

Design Specifications Group Properties by Variant, Size, and State

The "design-specifications" guideline documents measurable visual specs — design properties, spacing, sizing, typography, and responsive behavior. The base properties map defines the default configuration — an open map of design property names to values. Values are always strings: either design token names (e.g., "button-primary-bg", "space-4") or raw CSS values (e.g., "#0055b3", "16px", "transparent"). Systems that do not use tokens simply provide raw values directly.

The variants, sizes, and states arrays each contain named entries with their own properties maps. Each entry is self-contained — it represents that condition's complete set of values, not an override of the base. For example, a "danger" variant entry carries its own token names (like "button-danger-bg") or raw values, independent of the base properties. The variantStates array handles variant×state combinations (e.g., primary+hover) where the visual treatment differs across variants, with each entry specifying both a variant and a state alongside its properties.

{
  "kind": "design-specifications",
  "properties": {
    "background": "button-primary-bg",
    "color": "button-primary-text",
    "border-radius": "4px",
    "border-color": "transparent"
  },
  "spacing": {
    "internal": { "icon-to-label": "space-2", "container-horizontal": "space-4" }
  },
  "variants": [
    {
      "name": "danger",
      "properties": {
        "background": "button-danger-bg",
        "color": "#ffffff",
        "border-color": "transparent"
      }
    }
  ],
  "sizes": [
    {
      "name": "small",
      "properties": {
        "font-size": "14px"
      },
      "spacing": {
        "internal": { "icon-to-label": "4px", "container-horizontal": "space-3" }
      }
    }
  ]
}

Tokens and the W3C Design Tokens Format

DSDS does not carry token values or platform API mappings. The W3C Design Tokens Format (DTCG) file is the single source of truth for resolved values and platform-specific identifiers. Use the source property on a token entity to link it to its DTCG definition:

{
  "type": "token",
  "name": "color.text.primary",
  "tokenType": "color",
  "source": "./tokens.json"
}

Token Names Are Unconstrained

Most entity types enforce ^[a-z][a-z0-9-]*$ on the name property. Tokens and token groups are the intentional exception — their names are unconstrained to accommodate DTCG and design tool naming conventions that use dots (color.text.primary), slashes (color/text/primary), or other separators.

Links Handle Both Resources and Relationships

The links array on each entity handles both external resources and entity relationships via a kind discriminator:

{
  "links": [
    {
      "kind": "source",
      "url": "https://code.acme.com/design-system/src/button/button.tsx",
      "label": "React component source"
    },
    {
      "kind": "alternative",
      "url": "https://design.acme.com/components/link",
      "label": "Link component (alternative)"
    }
  ]
}

Standard external types: source, design, storybook, documentation, package, repository. Standard relationship types: alternative, parent, child, related. Custom types are permitted.

Extensions Preserve Interoperability

Tool-specific internal identifiers go in $extensions using namespaced keys. Extensions are available on the root document, on each documentation group, and on each entity:

{
  "$extensions": {
    "com.designTool": { "componentId": "abc123def456" },
    "com.storybook": { "storyId": "components-button--primary" }
  }
}

Rule of thumb: If it's a URL a human would click, it belongs in links. If it's an internal identifier consumed programmatically by a specific tool, it belongs in $extensions.

Systems of Systems: Extends

Large organizations often maintain a core design system shared across the company and one or more extension systems that layer product-specific components, tokens, and guidelines on top of it. The extends mechanism makes this relationship explicit at two levels.

Document-level extends

The root extends property declares that the entire document inherits from a base DSDS document. It names the core system, optionally provides a URL to the base document, and records the version being extended:

{
  "dsdsVersion": "0.1",
  "extends": {
    "system": "Acme Core Design System",
    "url": "https://design.acme.com/v2/core.dsds.json",
    "version": "2.0.0",
    "description": "Enterprise extension layering admin components and stricter a11y rules on the core system."
  },
  "documentation": [ "..." ]
}

Entity-level extends

Individual components and tokens can declare that they extend a specific base entity from the parent system. The entity-level extends includes a name (matching the base entity), an optional system override, and an optional modifications array that serves as a human-readable changelog:

{
  "kind": "component",
  "name": "button",
  "extends": {
    "name": "button",
    "description": "Adds an 'enterprise' variant and a 'theme' prop.",
    "modifications": [
      { "type": "added",     "target": "variant:enterprise", "description": "High-emphasis enterprise brand variant." },
      { "type": "added",     "target": "prop:theme",         "description": "'default' | 'admin' sub-brand switcher." },
      { "type": "inherited", "target": "guideline:anatomy",  "description": "Anatomy inherited from core without changes." }
    ]
  },
  "displayName": "Button",
  "description": "Enterprise Button — extends core with an enterprise variant and theme prop.",
  "status": "stable",
  "documentBlocks": [ "..." ]
}

What the schema does — and does not — do

The extends declarations establish the relationship between a base system and its extensions. Merge and resolution semantics — which guidelines are inherited, which are overridden, which are appended — are the responsibility of consuming tooling, not the schema. DSDS provides a portable, machine-readable way to declare these relationships; tools decide how to resolve them.

Example file: See examples/extension-system.dsds.json for a complete enterprise extension system demonstrating document-level extends, entity-level extends on both components and tokens, the modifications changelog, and net-new entities that exist only in the extension.

Default Values

Several optional properties declare default values via the JSON Schema default keyword. Validators do not inject these — they are advisory hints for tools and consumers that indicate what value to assume when the property is omitted.

Property Schema Default Meaning when omitted
guidelineEntry.kind guideline.schema.json "informational" The guideline is advisory context with no enforcement expectation.
link.required link.schema.json false The linked artifact is an optional enhancement, not a dependency.
anatomyEntry.required anatomy.schema.json false The anatomy part is conditionally rendered, not always present.
apiProperty.required api.schema.json false The property does not need to be provided by the consumer.
apiProperty.deprecated api.schema.json false The property is not deprecated.
ariaAttribute.required accessibility.schema.json false The ARIA attribute is conditionally required or optional.
richText.format rich-text.schema.json "markdown" Text content is interpreted as CommonMark.

Schema Architecture

The schema is organized into three directories plus a root schema:

Directory Contents
common/ Shared primitives — richText, statusObject, link, example, extensions, metadata, useCase
entities/ Entity types — component, token (+ tokenGroup), theme, style, pattern
document-blocks/ Document block types — 13 type schemas + scoped unions (componentDocumentBlock, styleDocumentBlock, patternDocumentBlock, tokenDocumentBlock)

The root dsds.schema.json defines the document structure and references entity schemas via a oneOf discriminated union. The dsds.bundled.schema.json is auto-generated by scripts/bundle.js for tools that require a single-file schema.

Property tables on the specification site are generated directly from the schema JSON — they are always in sync with the schema and cannot drift from the implementation.

Design Principles

  1. Structure enables quality. A defined format creates a floor of quality and completeness.
  2. Guidance without justification is incomplete. Every best practice must answer "why?"
  3. Documentation should be portable. Teams change tools. Documentation should survive the transition.
  4. Education is a responsibility. Explain what, why, and how.
  5. Specificity over subjectivity. "Use sparingly" is not guidance. "Limit to one per surface" is.
  6. Schema is the source of truth. Property tables are generated from schema JSON, not hand-written. Prose provides context; schemas provide structure.

Contributing

This is an early-stage specification (v0.1). Feedback is welcome:

  • Open an issue for questions, suggestions, or problems with the spec.
  • Open a PR for proposed changes to the spec, schema, or examples.

License

This project is open source. See LICENSE for details.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors