- Home
- Design system
- Sds manifests
SDS manifests
Consume SDS component metadata for code generation, validation, and agent workflows.
Overview
SDS manifests are machine-readable JSON descriptions of Soracom Design System components. They describe which HTML elements, modifiers, structures, attributes, examples, CSS custom properties, and accessibility requirements a component supports.
Use manifests when tooling needs to generate or validate SDS markup without guessing component APIs. The SDS MCP server uses these manifests, but scripts and agents can also consume the JSON files directly.
Component documentation remains important for design and usage guidance. A manifest provides a structured component contract; it does not replace the human-readable documentation linked by docUrl.
Published files
The stable manifests are published with the latest SDS release.
| Artifact | URL |
|---|---|
| All component manifests | https://assets.soracom.io/sds/latest/manifests.json |
| One component | https://assets.soracom.io/sds/latest/{component}/manifest.json |
| Button example | https://assets.soracom.io/sds/latest/ds-button/manifest.json |
manifests.json is an object keyed by component name. Each value contains the same component data available from its individual manifest.json file. Use the combined file for discovery or when processing several components; use an individual file when only one component is needed.
Some components also declare supporting registries. For example, ds-icon links to the icon catalog and ds-plan links to the plan catalog. Registry paths are relative to the component manifest URL and must be resolved from that URL rather than hard-coded.
Release channels
Replace latest in an asset URL with the channel appropriate for the task.
| Channel | Use |
|---|---|
latest | Current stable SDS release. Recommended for interactive agent work. |
A version such as 3.31.8 | Reproducible builds, tests, and long-running migrations. |
beta | Previewing unreleased manifest changes. Content can change without notice. |
Pin a version when the same input must produce the same result later. Do not combine component manifests or registries from different channels or versions.
Discover components
Download the combined manifest and list its component names, descriptions, and documentation URLs:
curl --fail --silent --show-error \
https://assets.soracom.io/sds/latest/manifests.json \
--output /tmp/sds-manifests.json
jq -r '
to_entries[] |
[.key, .value.description, (.value.docUrl // "No documentation URL")] |
@tsv
' /tmp/sds-manifests.json
Filter by category or supported root element before selecting a component:
# List element components that can use a native button element.
jq -r '
to_entries[] |
select(.value.category == "elements") |
select(.value.htmlElements | index("button")) |
.key
' /tmp/sds-manifests.json
Read one component from the combined file:
jq '."ds-button"' /tmp/sds-manifests.json
Manifest fields
Every manifest contains component identity and modifier support. Other fields are included when the component has corresponding structured metadata.
| Field | Meaning |
|---|---|
name | SDS root class or custom element name. |
description | Short description of the component. |
docUrl | Human-readable component documentation, when available. |
category | Component grouping such as elements, containers, utility, or specialized. |
htmlElements | Valid root HTML elements or custom element names. |
isWebComponent | Whether the component is implemented as a web component. |
modifiers | Modifier groups and the values supported by this component. |
structure | Required children, named parts, patterns, and default attributes. |
attributes | Web component attributes, allowed values, defaults, or validation patterns. |
webComponentApi | Tag name, JavaScript properties, observed attributes, and events. |
dataAttributes | Supported data-* attributes and their value types. |
cssCustomProperties | Component-level CSS custom properties, defaults, and descriptions. |
accessibility | Roles, ARIA attributes, and implementation notes. |
examples | Named examples of valid component markup. |
registries | Related data files, expressed as paths relative to the manifest. |
Fields such as structure, attributes, and accessibility are optional. Their absence means that the manifest does not provide that information; an agent must not assume that the component has no structural, attribute, or accessibility requirements.
Modifier support
Each entry under modifiers has a support value:
| Support | Meaning | Agent behavior |
|---|---|---|
all | The component accepts the SDS-wide values for that modifier group. | Look up the current group values before choosing one. Do not invent a value. |
subset | The component accepts a defined subset of an SDS-wide group. | Use only the manifest’s values. |
custom | The component has its own values for this group. | Use only the manifest’s values. |
For example, this shortened ds-button data allows the listed variants but refers to the SDS-wide icon catalog:
{
"name": "ds-button",
"htmlElements": ["button", "a"],
"modifiers": {
"variant": {
"support": "custom",
"values": ["--primary", "--plain", "--feature", "--link"]
},
"icon": {
"support": "all"
}
},
"structure": {
"requiredChildren": ["span"],
"wrapContent": "span",
"defaultAttributes": {
"type": "button"
}
}
}
The raw component manifest does not enumerate values for a group with support: "all". Use the related registry when one is declared, consult the linked documentation, or use the MCP server’s list_component_modifiers tool to retrieve the current global values.
Load a manifest in an agent tool
The following Node.js script loads a component manifest and any registries it declares. It validates the component name and resolves each registry path relative to the manifest URL.
const channel = process.env.SDS_CHANNEL ?? "latest";
const component = process.argv[2] ?? "ds-button";
if (!/^(beta|latest|\d+\.\d+\.\d+)$/.test(channel)) {
throw new Error(`Invalid SDS channel: ${channel}`);
}
if (!/^ds-[a-z0-9-]+$/.test(component)) {
throw new Error(`Invalid SDS component name: ${component}`);
}
const manifestUrl = new URL(
`https://assets.soracom.io/sds/${channel}/${component}/manifest.json`,
);
async function readJson(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to load ${url}: HTTP ${response.status}`);
}
return response.json();
}
const manifest = await readJson(manifestUrl);
const registryEntries = Object.entries(manifest.registries ?? {});
const registries = Object.fromEntries(
await Promise.all(
registryEntries.map(async ([name, registry]) => [
name,
await readJson(new URL(registry.path, manifestUrl)),
]),
),
);
console.log(JSON.stringify({ manifest, registries }, null, 2));
Save the script as load-sds-manifest.mjs, then run it for a stable or pinned version:
node load-sds-manifest.mjs ds-button
SDS_CHANNEL=3.31.8 node load-sds-manifest.mjs ds-plan
An agent can run this loader before editing code, or an agent host can expose its result as read-only context.
Agent workflow
A reliable SDS code-generation workflow is:
- Load
manifests.jsonand select a component by purpose, category, valid root element, anddocUrlguidance. - Load the selected component manifest and all declared registries from the same SDS channel.
- Start from the closest named
exampleorstructure.patternsentry rather than creating markup from memory. - Use only declared modifier and attribute values. Resolve
support: "all"groups from current SDS data before selecting a value. - Apply
structure.requiredChildren,structure.defaultAttributes, attribute patterns, and accessibility notes. - Validate the completed markup against the same manifest before returning or writing it.
- Report any requirement that cannot be verified from the available fields instead of guessing.
Example agent instruction
Give an agent a direct instruction that defines the manifest as required input and specifies how uncertainty should be handled:
Build the action controls with SDS components.
Before editing:
1. Fetch https://assets.soracom.io/sds/latest/manifests.json.
2. Select the appropriate components from their descriptions and docUrl values.
3. Read each selected component's manifest and any relative registries.
When generating markup:
- Use a declared example or structure pattern as the starting point.
- Use only valid root elements, modifier values, attributes, and child structure.
- Apply default attributes and accessibility notes.
- Treat a missing field as unknown, not as permission to invent an API.
- Validate the final HTML against the manifest and explain unresolved items.
For reproducible agent runs, replace latest with the SDS version used by the target application.
Generation examples
Generate an accessible action button
Suppose an agent is asked to create a destructive action. The ds-button manifest provides:
The agent can adapt that example while preserving its contract:
<button
class="ds-button --primary --icon-delete --alert"
type="button"
>
<span>Delete SIM</span>
</button>
The visible text supplies an accessible name, the required child is present, and the explicit button type prevents accidental form submission.
Correct invalid SDS markup
Input generated without a manifest might use standard BEM class names and omit required structure:
<button class="ds-button ds-button--primary">Delete SIM</button>
The manifest tells the agent to use the suffix-only modifier, wrap content in span, and add the default button type:
<button class="ds-button --primary" type="button">
<span>Delete SIM</span>
</button>
The block class appears only on the root. Child and modifier classes use SDS suffix forms such as __part and --modifier; do not generate repeated forms such as ds-button--primary.
Validate web component attributes
The ds-plan manifest declares attribute constraints that an agent can check before producing markup:
function validateAttribute(manifest, name, value) {
const attribute = manifest.attributes?.[name];
if (!attribute) return { valid: false, reason: "Unknown attribute" };
if (attribute.values && !attribute.values.includes(value)) {
return { valid: false, reason: "Value is not in the allowed list" };
}
if (attribute.pattern && !new RegExp(attribute.pattern).test(value)) {
return { valid: false, reason: "Value does not match the required pattern" };
}
return { valid: true };
}
Using the declared size values, 15-digit imsi pattern, and planus key from the linked plan registry, an agent can generate:
<ds-plan
plan="planus"
bundle="5GB"
imsi="295050123456789"
size="small"
></ds-plan>
The manifest marks the plan attribute with allowUnknown: true. An agent may use the linked plan registry for suggestions and known display metadata, but it must not reject a plan solely because that plan is absent from the registry.
Use a web component API
The ds-theme manifest exposes JavaScript API metadata in webComponentApi, including the allowed value property and the ds-theme-change event. An agent can use those exact names instead of inferring an event API:
<ds-theme value="system" aria-label="Color theme"></ds-theme>
<script type="module">
const theme = document.querySelector("ds-theme");
theme.addEventListener("ds-theme-change", (event) => {
console.log("Theme changed to", event.detail.value);
});
</script>
Direct JSON or MCP
Both approaches use the same manifest data.
| Need | Recommended approach |
|---|---|
| Use SDS from an MCP-compatible coding agent | SDS MCP server |
| Discover components or modifiers conversationally | SDS MCP server tools |
| Build CI validation or a custom generator | Direct JSON consumption |
| Keep an auditable, version-pinned input | Direct JSON with a versioned URL |
| Work without agent network access | Fetch and store a version-pinned snapshot before the run |
When MCP is available, use get_component_info, generate_component_html, and validate_sds_html for common workflows. Direct manifest consumption is useful when building a specialized tool or when the agent needs the complete raw contract.
Validation checklist
Before accepting agent-generated SDS markup, verify that: