How to use
- Copy the installation command and review the source package before installing it in your own agent environment.
- Check the source document for required tools, credentials and supported hosts.
- Describe your input and desired deliverable; review the output against the source material.
npx skills add https://github.com/alma-oss/spirit-design-system --skill spirit:figma-to-codeBefore you start
- Installation does not include a model subscription, API allowance or permission to access your files.
- Repository stars and installation counts describe activity, not an independent quality or security test.
Rendered from the source repository. Headings, examples, code, tables, links, and referenced images are preserved.
Figma to Code
Convert a Figma design into React with @alma-oss/spirit-web-react. Target this repository’s current main / latest APIs. Do not invent APIs, tokens, breakpoints, routes, data, or assets.
Do not use this skill for:
- Design-system review or handoff reports — use
/spirit:review-figma-design - Writing or updating Figma Code Connect mappings
- Building or syncing designs in Figma from code
- Vanilla
packages/webmarkup or other non-React packages
References
- Component selection
- Layout
- Typography
- Cards
- Forms
- Accessibility:
/spirit:accessibility
Source Authority
Resolve conflicts in this order. A later source does not override an earlier one.
- Valid APIs, defaults, deprecations, composition — current Spirit source in this order:
implementation, public types, packages/web-react/DEPRECATIONS.md, then the component README. If those disagree, implementation and types win. Do not copy stale README examples.
- Component identity and variants — Figma Code Connect mappings (when present).
- Visual measurements, tokens, assets — Figma design context, variables, and exported assets.
- Behavior, copy, routing, and accessibility — product requirements and the surrounding app.
Normalize Code Connect and generated snippets to the current API: replace removed or deprecated props, omit values equal to current defaults, and keep design intent. Code Connect is not always complete or up to date. Nested CardLink is a common omission: a “Card Basic” snippet with a bare CardTitle is not proof the card is static if the title node uses a themed/link/… token. See Cards.
Never guess from screenshots. If Figma data, Code Connect, or product context is missing, stop, list the assumptions, and ask. Do not silently invent breakpoints, icon names, colors, spacing, accessible names, hrefs, or image sources.
Workflow
1. Acquire the Design
If a Figma design-to-code skill is available, follow it before calling get_design_context.
- Parse a Figma URL when provided (
fileKey,nodeIdfromnode-idwith-→:). If the MCP
needs fileKey even for the current selection, ask for a node URL instead of guessing.
- Call
get_design_contextfirst. Treat the returned code as a reference, not paste-ready
output. Adapt it to Spirit React.
- Use supporting tools only when needed: metadata to pick a node, variable definitions for tokens,
screenshots for visual comparison, asset download for images/icons, motion context for animation.
- When the MCP lets you set client context, request React and TypeScript.
2. Map Structure, Not Figma’s Layer Count
Preserve reading order, visual grouping, max-width boundaries, and Spirit composition contracts. Figma frames often exist for editing, clipping, or naming — they are not 1:1 DOM nodes.
- Use a Spirit component when it owns the needed semantics, behavior, or styling contract. Match
Figma names and layout patterns first, then search for an existing composite (PricingPlan + Matrix, ScrollView, Stack). See Component selection.
- Use native semantic elements (
p,ul/ol/li,article,form) when no Spirit component is
responsible, including inside Card body content.
- Do not wrap extra layout components around Card, Dialog, Drawer, or other families that require a
flat, ordered composition.
- Add
Containeronly where a distinct width constraint exists. See Layout. - When the design is a form, wrap both the field area and the action buttons in a named native
<form>. See Forms.
3. Choose Components and Props
- Route from Figma component names, text styles, and Code Connect to Spirit components using
- Confirm props against current types and defaults. Omit props that match defaults.
- Heading and
UNSTABLE_DisplayHeadingelementTypeis always required. CardTitle already
defaults to h4. Map Figma Display/\* styles to UNSTABLE_DisplayHeading, not Heading.
- Keep exact icon identifiers from Figma:
Iconusesname,IconBoxusesiconName. Do not
replace placeholder with a “better” icon.
- Map Figma spacing tokens such as
--global/spacing/space-1400tospacing="space-1400". - Map CSS alignment to Spirit
alignmentX/alignmentY(flex-start→left/top,
flex-end → right/bottom). On vertical Flex, align-items is alignmentX. On horizontal Flex, justify-content is alignmentX.
- Prefer
Box colorSchemefor semantic surfaces. Use component-specific color dictionaries; do
not reuse Heading/Text colors on Box, Section, Link, or Button.
Deprecated or removed APIs must not appear in new code. Current traps:
emphasis→fontWeightandisItalic- Flex
row/column→horizontal/vertical(plushorizontal-reversedwhen needed) hideOnCollapse→isDisposableon UncontrolledCollapseCardDescription,CardTitle headingProps,CardLink isExternal, Buttonvariant
If Code Connect still emits those, tell the user and emit the current API.
4. Responsive Behavior
Spirit breakpoints are mobile from 0, tablet from 48rem, desktop from 80rem (typically 768px and 1280px). Do not infer a 1024px desktop breakpoint from frame width.
- Encode only transitions supported by Figma frames, variables, or annotations.
- A scalar applies at every breakpoint. Partial objects cascade forward
({ mobile: 'small', desktop: 'large' } keeps small on tablet).
- If only one frame is provided, match that frame. Do not invent other breakpoints.
- Figma layout guides (column counts, gutters) are often absent from MCP output. If the user
mentions them, implement with Grid and ask when the column count is unclear. Infer column counts from how the frame divides the parent (tokens and the 12-column system), not from a pixel formula. See Layout.
5. Accessibility
Apply /spirit:accessibility. This step is a semantics pass, not a prop re-check. Cover landmarks, heading outline, list markup, and role/elementType from meaning — not from the Figma component name.
- Choose
elementTypefrom document outline, not from visual size. Visual style and semantics
are independent.
- Prefer not to skip heading ranks; fix the outline rather than forcing a visual size onto the
wrong tag. Keep the page h1 out of an anonymous <section>. See Layout.
- Repeating cards or items that are a list in meaning use
ul/olwithli, not a bare Flex/Grid
of divs.
- Preserve DOM source order. If Flex
horizontal-reversedor similar changes visual order, keep
the accessible reading order correct.
- Give controls accessible names, states, and relationships (label, description, error, required).
- Decide decorative vs informative for images and icons; do not invent alt text from pixels.
- Do not nest interactive elements. A stretched CardLink may coexist with footer buttons because
Card raises those controls; do not add extra wrapping links.
- Honor reduced-motion and focus management for Dialog, Drawer, Dropdown, and similar overlays.
- Personal-data autocomplete and checkbox-revealed field ARIA live in
/spirit:accessibility.
6. Assets
- Prefer Figma MCP assets, files already in the repo, or an explicit product image source.
- MCP asset URLs expire; for committed code, download the bytes or wire the app’s image source.
- Do not use
picsum.photosor other random remote placeholders. - If no asset is available, use a clearly labeled local placeholder and flag it in the handoff.
Validation
Validation is required, not optional. After implementation:
- Confirm every Spirit prop against current types. Fix invalid token names and removed APIs.
- Run linters on edited files (
ReadLintsin this repo) and fix new issues. - Run relevant unit tests when the change lives in this repository.
- Render and compare. In this repo: start Vite with
make startoryarn start
(http://localhost:3456/packages/web-react/), inspect with Playwright MCP, then use Docker Make targets (make test-e2e, make test-e2e-a11y) for suite runs. Do not skip visual comparison silently.
- Re-fetch Figma context if the implementation drifted from tokens, icons, or composition.
If a gate cannot run, say so in the handoff (verified vs unverified) and list what was skipped.
Implementation Checklist
- \[ \] Design acquired with
get_design_context; missing data flagged, not guessed - \[ \] Code Connect intent kept; snippets normalized to current APIs and defaults
- \[ \] Icon identifiers unchanged (
Icon name,IconBox iconName) - \[ \] No deprecated or removed APIs (
emphasis,row/column,hideOnCollapse,CardDescription) - \[ \] Semantic structure preserved; Figma-only wrapper frames not copied 1:1
- \[ \] Existing composite used where one covers the pattern (
PricingPlan,ScrollView,Stack) - \[ \] Widths expressed as Grid column spans or Container
sizetokens, not one-off pixel formulas - \[ \] Card vs Box decided by composition (artwork/title/footer/link), not Figma name
- \[ \] Card titles with
themed/link/…tokens useCardLinkeven if Code Connect omitted it - \[ \] Page
h1not nested in an anonymous Section; repeating cards use list markup - \[ \] Heading
elementTypeset; Display/\* →UNSTABLE_DisplayHeading; typography mapped by text style, not by size alone - \[ \] Form wraps fields and actions; submit first in DOM; personal-data autocomplete per
/spirit:accessibility - \[ \] Responsive values exist only where Figma supports them; breakpoints are Spirit tokens
- \[ \] Assets are stable; alt/decorative decisions are explicit
- \[ \] Accessibility, TypeScript, lint, render, and (when in this repo) tests/a11y checks ran — or the handoff is marked unverified
- \[ \] Unclear patterns were asked about instead of improvised



