Skip to main content

Overview

Ditto spec files use YAML frontmatter in .ditto.md files. Everything lives between the --- delimiters; the markdown body below the closing --- is unused. There are two types: workspace specs and component specs.

Workspace spec

A repo has a single workspace.ditto.md somewhere under the CLI’s configured roots. It holds universal style guide rules that carry no tags — these apply to every surface in every component. It also carries an inventory of all tags available on the platform.
---
workspace: true
# Managed by Ditto — do not edit below
tags: [body, button, call-to-action, dialog-title, heading, nav]
rules:
  - name: Write in active voice
    description: Lead with verbs, avoid passive constructions
    section: Voice & Tone
locales:
  de-DE:
    - name: Use informal address
      description: Use "Du" instead of "Sie" for all user-facing copy
      section: Formality
---
KeyManaged byDescription
workspaceDeveloperMust be true. Marks this as the workspace spec.
tagsCLI (pull)All tags that exist on the platform. Used as a reference when tagging surfaces.
rulesCLI (pull)Universal style guide rules with no tag scope — apply to all surfaces everywhere.
localesCLI (pull)Locale-scoped style guide rules, keyed by locale code.

Component spec

Each component that renders user-facing text gets an index.ditto.md Ditto spec file in its directory.
---
component: DialogueModal
tags: [dialog, confirmation]
surfaces:
  headline:
    tags: [heading, dialog-title]
    maxLength: 60
  content:
    tags: [body, dialog-body]
    maxLength: 240
  actionText:
    tags: [call-to-action]
    maxLength: 25
  cancelText:
    tags: [button]
    maxLength: 25
# Managed by Ditto — do not edit below
rules:
  - name: Confirmation dialogs should be direct
    description: Keep confirmation copy terse and unambiguous
    section: Voice & Tone
  - surface: actionText
    name: Calls to action should use active voice
    description: Always lead with a verb
    examples:
      - from: "Your settings"
        to: "Open settings"
    section: Voice & Tone
  - term: sign up
    disallowed:
      - signup
      - sign-up
    description: Always use as two words (verb form)
    section: Terminology
locales:
  de-DE:
    - name: Use informal address
      description: Use "Du" instead of "Sie" for all user-facing copy
      section: Formality
---

component

The component name (string). Set when you run ditto-spec scaffold.

tags

Component-level tags (array of strings) that describe what the component is in your design system — e.g. [dialog, confirmation] for a confirmation modal, [card, product] for a product card. Style guide rules matching any of these tags apply to all surfaces in the component, cascading content governance to every piece of text it renders. Edit these freely. This is the primary mechanism for integrating Ditto specs into a design system. A component’s tags capture its role as a design system element, pulling in rules about how that type of component should read — tone, voice, constraints. The individual surfaces then carry their own tags for more specific rules (see below).

surfaces

Each key is a surface — a distinct piece of user-facing text the component renders.
PropertyRequiredDescription
tagsYesPer-surface tags that describe the text’s role — e.g. [heading, dialog-title], [call-to-action]. Used for matching style guide rules to this specific surface.
maxLengthNoMaximum character length. A hard layout constraint, not a stylistic preference.

rules

Populated by ditto-spec pull. Style guide rules come in two shapes:
ShapeFieldsScope
Style rulename, description, examples (optional {from, to} pairs), sectionWithout surface: all surfaces. With surface: "<key>": that surface only.
Terminology entryterm, disallowed, description, sectionWithout surface: all surfaces. With surface: "<key>": that surface only.

locales

Populated by ditto-spec pull. Keyed by locale code (e.g. de-DE). Contains the same style guide rule shapes as rules, scoped to a specific locale. Locale-scoped rules apply in addition to base rules when writing copy for that locale.

Style guide rule hierarchy

ScopeWhereApplies to
Workspaceworkspace.ditto.md rules[]Every surface in every component
Component-levelComponent’s rules[], no surface fieldEvery surface in this component
Per-surfaceComponent’s rules[], with surface: "<key>"That one surface
Locale-scopedlocales.<code>[] (workspace or component)Same hierarchy as above, but only when writing copy for that locale
Base style guide rules always apply. Locale-scoped rules apply only when writing copy for the matching locale — they never conflict because each locale is a separate scope.

Developer-owned vs CLI-managed keys

KeysOwnerEdit by hand?
component, tags, surfacesDeveloperYes — add, remove, and modify freely.
rules, locales, workspace tagsCLI (pull)No — overwritten on every pull.
Never edit rules or locales by hand. Run ditto-spec pull to update them from the platform.

Surface naming conventions

ScenarioKey to useExample
String propThe prop nametitle, description
Nested propDot notationprimaryAction.label
Children prop$children$children
Hardcoded/internal stringDescriptive role nameheadline, bodyText, submitLabel
Check the tags key in workspace.ditto.md for tags available on the platform. Prefer reusing an existing tag over creating a new one — only tags that exist on the platform will match style guide rules.

Tagging in a design system

Ditto specs support two levels of tagging that mirror how design systems organize components:
  • Component-level tags describe the component itself — its role in the design system. A DialogueModal tagged [dialog, confirmation] pulls in style guide rules about how confirmation dialogs should read. These rules apply to every surface in the component.
  • Surface-level tags describe each individual piece of text — its function within the component. An actionText surface tagged [call-to-action] pulls in rules specific to CTAs (e.g. “lead with a verb”). These rules apply only to that surface.
Both levels work together. For a DialogueModal:
tags: [dialog, confirmation]        # rules about dialogs apply to ALL surfaces
surfaces:
  headline:
    tags: [heading, dialog-title]    # + rules about headings apply here
  actionText:
    tags: [call-to-action]           # + rules about CTAs apply here
  cancelText:
    tags: [button]                   # + rules about buttons apply here
The headline surface inherits style guide rules matched by dialog, confirmation (from the component), plus rules matched by heading, dialog-title (from the surface). If a rule matches both levels, it appears once at component level — broader scope wins. This means you can create style guide rules on the Ditto platform scoped to design system concepts (dialog, card, form, navigation) and have them automatically cascade to every component tagged with that concept, while surface-level tags layer on more specific guidance.

File discovery

The CLI searches directories listed in the roots config for any *.ditto.md files. workspace.ditto.md is identified by its workspace: true key; all other .ditto.md files are treated as component Ditto specs.