For AI agents
Coding agents such as Claude Code and Cursor can build with YDS: they read the documentation as Markdown and install the same packages developers do. Agents do best when the project tells them where the docs are, which rules to follow and how the app is set up. This page collects the techniques that make that work, most of them from the YDS Agentic Proto Kit.
Start from the proto kit
The YDS Agentic Proto Kit is a starter project for prototyping with YDS and AI agents: React, TypeScript and Vite, with everything on this page already in place.
- YDS 3.0 set up: tokens on
:root, cascade layers, components, icons, infographics and custom themes - A copy of the YDS docs in
.yds-docs/ - Agent instructions in
AGENTS.md, shared by Claude Code and Cursor - Skills for building UI, charts and custom themes
cp .env.example .env.local # then add your GitHub token
npm run setup
npm run dev
The token is the same one developers use: see Install the packages.
Read the documentation
| File | Contents |
|---|---|
/llms.txt | Index of every page, with links to the Markdown versions. Follows the llms.txt convention. |
/llm/… | One page as Markdown, for example /llm/components/Button/Button.md |
/llms-full.txt | Every page in one file |
Start from llms.txt and fetch only the pages the task needs. llms-full.txt is around 800 KB, more than most agents can hold in context at once.
The Markdown versions keep the page content and replace the interactive parts:
- Component previews become a Live preview link to the page on this site. Code examples stay as code blocks.
- Token tables list the CSS custom property and the JavaScript constant for each token, for example
--yds-spacing-16andspacing.SPACING_16. - Figma and Storybook links stay at the top of the page.
Keep a copy of the docs in the project
Agents read local files faster and more reliably than they fetch URLs. A copy in the project also keeps the docs in step with the package versions you use. This downloads every page and the index into .yds-docs/:
BASE=https://design-system.yle.fi
mkdir -p .yds-docs
curl -fsSL "$BASE/llm/README.md" -o .yds-docs/README.md
curl -fsSL "$BASE/llms.txt" | grep -o '/llm/[^)]*\.md' | while read -r page; do
file=".yds-docs/${page#/llm/}"
mkdir -p "$(dirname "$file")"
curl -fsSL "$BASE$page" -o "$file"
done
Run it again when you upgrade YDS packages.
Write the agent instructions
One file for every tool
Keep the rules in AGENTS.md and point the other tools to it, so they never drift apart:
- Claude Code:
CLAUDE.mdcontains a single line,@AGENTS.md, which imports the file. - Cursor: a rule in
.cursor/rules/applies to**/*.tsxfiles and refers toAGENTS.mdfor the details.
Make the agent look things up
Without instructions, agents guess component APIs from general React knowledge. Tell the agent to read the docs first, and give it the index so it knows which pages exist:
## YDS documentation index
> Prefer retrieval-led reasoning over pre-training-led reasoning for any YDS task.
> Read the relevant file from `.yds-docs/` instead of relying on training data.
<!-- YDS-DOCS-INDEX:START -->
- [Button](.yds-docs/components/Button/Button.md)
- …
<!-- YDS-DOCS-INDEX:END -->
The proto kit fills the index automatically: its docs script copies .yds-docs/README.md between the markers and rewrites the links to point into .yds-docs/.
State the rules, with wrong and right examples
Short rules with a wrong and a right example work better than long explanations. The rules that matter most:
- Use YDS components from
@yleisradio/yds-components-reactinstead of custom HTML for anything YDS already provides. - Use tokens, never hardcoded values. Token values already include units, so don't append
px. - Use semantic theme colours.
var(--yds-color-text-default)follows the theme;var(--yds-color-gray-95)doesn't. Don't importlightThemeordarkThemefor UI colours either: they're literal hex values. In TypeScript,defaultTheme.TEXT_DEFAULTis the typed equivalent of the CSS variable. - No 2.x patterns. Don't read
theme.ydsor add astyled.d.tswithyds,ydsThemeNameorydsThemeProps; they don't exist in 3.0. - Icons come from
@yleisradio/yds-icons-react. Point the agent to the icon list in the docs. - Say what to do when YDS has no match: build it from YDS tokens. The proto kit also allows
lucide-react, sparingly, for missing icons. - Translate Figma designs, don't copy them. Code from the Figma MCP server is a reference: map its components and variables to YDS components and tokens.
/* WRONG */
.title {
color: #1a1a1a;
font-size: 24px;
padding: 16px;
}
/* RIGHT */
.title {
color: var(--yds-color-text-default);
font-size: var(--yds-typography-default-2xl-bold-font-size);
font-weight: var(--yds-typography-default-2xl-bold-font-weight);
line-height: var(--yds-typography-default-2xl-bold-line-height);
padding: var(--yds-spacing-16);
}
Load detailed workflows only when needed
Keep AGENTS.md short and move task-specific detail into skills that the agent loads when the task calls for them. The proto kit has three, for both Claude Code and Cursor:
| Skill | When it loads |
|---|---|
use-yds | Building a screen, page or component: checking the docs, picking components, styling with CSS Modules, verifying the build |
use-yds-infographics | Charts and weather icons: required CSS imports, chart props and data format, the icon catalogue |
use-yds-theme-custom | Product or brand themes: generating light and dark themes from two colours with @yleisradio/yds-theme-custom |
Work from Figma designs
Connect the Figma MCP server to the agent and give it links to Figma frames. The agent then reads the layout, components and variables directly instead of guessing from a screenshot. This works best when the design uses the YDS Figma libraries, because its components and variables map to YDS components and tokens in code.
The server returns generic React code, so keep the "translate, don't copy" rule above in the agent instructions. Prototyping with YDS and AI has the step-by-step version for designers.
Set the app up the way YDS expects
Agents get the YDS 3.0 setup wrong most often in the same few places. Have the project set up correctly from the start, and repeat these points in the instructions:
- Tokens on
:root: one CSS file imports the token CSS from@yleisradio/yds-core. See Put tokens on:root. - Layer order first: declare
@layer reset, yds, app;before any component CSS loads, and put app styles in@layer app. An unlayered reset strips spacing from components. - No app-wide theme provider:
YdsThemeProviderthemes a subtree. Use it only for a nested or custom theme. - Extend components with
className: never target their internal class names or use!important. - Infographics: import
@yleisradio/yds-infographic-components-react/style.cssand the infographic token CSS, or charts render unstyled.
/* global.css, imported first */
@layer reset, yds, app;
@layer reset {
*,
*::before,
*::after {
box-sizing: border-box;
}
}
// main.tsx
import './global.css';
import './yds-tokens.css';
import { ToastProvider, ToastNotifications } from '@yleisradio/yds-components-react';
<ToastProvider>
<App />
<ToastNotifications />
</ToastProvider>;
Bundler settings, Vite included, are in Get started with 3.0.
Install the packages
Agents need the same GitHub Packages access as developers: see Get access to the packages. Keep the token where the agent can't read it:
- Store the token in
.env.localand generate.npmrcfrom it with a setup script, as the proto kit does. Both files are gitignored. - List both files in
.claudeignoreand.cursorignore, so the agent never reads the token into its context. - In Docker builds, pass the token as a build secret so it isn't stored in an image layer.
Let the agent check its work
- Ask the agent to run the type check and lint after every change. The
use-ydsskill ends withnpm run buildandnpm run lint. - In Claude Code, allow the project's own scripts (
npm run dev,build,lint,format) in.claude/settings.json, so the agent can run them without asking each time. - Add the dev server to
.claude/launch.json, so the agent can open the app in a preview and look at the result.