Wix Design System
WixOfficialPublished by Wix
- Skill
- Tool integration
- Software development
- MIT
- Low risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The Wix Design System documentation navigator provides a command-line interface to interact with the @wix/design-system library. It allows developers to quickly search for components, retrieve detailed property definitions, view usage examples, and access testkit APIs for various testing frameworks. The skill also includes mapping tables for design elements and spacing tokens to ensure consistent UI implementation.
What it does
- Searches for UI components based on keywords
- Retrieves component property definitions and types
- Provides specific JSX usage examples for components
- Generates testkit import snippets and driver API documentation
- Maps design elements to corresponding WDS components
- Provides conversion tables for pixel-to-SP spacing tokens
When to use it
- When building UI components using the Wix Design System
- When you need to verify component props or available examples
- When writing automated tests using component testkits
- When looking for the correct icon or layout component
- When you need to convert design spacing to WDS tokens
Advantages
- Reduces time spent navigating large documentation files
- Ensures consistent use of design tokens and components
- Simplifies testkit setup across different testing frameworks
- Handles monorepo and workspace path discovery automatically
Usage examples
- “What component should I use for a modal dialog?”
- The agent searches the WDS documentation and suggests using the Modal component combined with CustomModalLayout.
- “Show me the props for the Button component.”
- The agent returns a list of all available props for the Button component, including their types and descriptions.
- “How do I use the Button testkit in Playwright?”
- The agent provides the specific import statement for the Playwright testkit and lists the available driver methods.
- “What is the SP token for 12px spacing?”
- The agent references the spacing table and identifies SP2 as the correct token for 12px in classic mode.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/wix/wix-design-system/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip wix-design-system.zip -d .agents/skills
Documentation by Wix
WDS Documentation Navigator
Prerequisite: @wix/design-system must be installed (npm i @wix/design-system or yarn add @wix/design-system).
Helper Script
This skill bundles scripts/wds.cjs — a Node.js helper that auto-discovers @wix/design-system in node_modules (handles monorepos and workspaces) and provides focused lookups. Run it from the user's project directory using the absolute path to the bundled script:
# WDS is the absolute path to this skill's scripts/wds.cjs
WDS="<this-skill-dir>/scripts/wds.cjs"
node $WDS search <keyword> # Find components by keyword
node $WDS component <Name> # Get props + example list (one component)
node $WDS components <Name1> <Name2>... # Same as `component`, but for several at once
node $WDS example <Name> "<ExampleName>" # Get a specific example
node $WDS testkit <Name> [method] # Get testkit imports + driver API
node $WDS icons <query> # Search for iconsWorkflow
Step 1: Find the right component
node $WDS search table
node $WDS search form input validation
node $WDS search modal dialog popupMultiple keywords are OR-matched. Returns component names, descriptions, and usage guidance.
Step 2: Get props and available examples
node $WDS component ButtonReturns the full props list (types and descriptions) plus a list of all available examples. For large prop files (>200 lines), returns a summary with prop names and types.
If you already know which several components you'll need (e.g. after Step 1 returned a shortlist), prefer the batch form to avoid one round-trip per component:
node $WDS components Button Card Table Input Text ThumbnailOutput is each component's props block separated by ---. Missing components are logged to stderr and skipped; the command only fails if every requested component is missing.
Step 3: Get a specific example
node $WDS example Button "Loading state"Returns the example description and JSX code. Matching is case-insensitive and supports substrings (e.g., "loading" matches "Loading state").
Step 4: Write tests with the component testkit
node $WDS testkit Button # Imports + full driver API for Button
node $WDS testkit Button click # Just the click() method detailsReturns import snippets for unidriver, vanilla, puppeteer, and playwright flavors plus the driver method API (name, args, return type, description). Method name matching is case-insensitive substring.
Step 5: Find icons
node $WDS icons Add Edit DeleteIcons are from @wix/wix-ui-icons-common. Each icon has a Small variant (e.g., Add + AddSmall).
Fallback: Direct File Access
If the script is unavailable, docs are at node_modules/@wix/design-system/dist/docs/:
components.md— component catalog (~978 lines, grep only)components/{Name}Props.md— props per componentcomponents/{Name}Examples.md— examples per component (grep^###for section list)components/{Name}Testkit.md— testkit imports + driver API per component (grep^###for method list)testkits.md— testkit catalog (list of components with generated testkit docs)icons.md— icon catalog (~818 lines, grep only)
Don't read these files fully. Grep for keywords, then read specific sections with offset/limit. See references/file-structure.md for the exact docs file layout and section shapes.
Quick Component Mapping (Design to WDS)
| Design Element | WDS Component | Notes |
|---|---|---|
| Rectangle/container | <Box> | Layout wrapper |
| Text button | <TextButton> | Secondary actions |
| Input with label | <FormField> + <Input> | Wrap inputs |
| Toggle | <ToggleSwitch> | On/off settings |
| Modal | <Modal> + <CustomModalLayout> | Use together |
| Grid | <Layout> + <Cell> | Responsive |
Spacing (px to SP conversion)
When designer specifies pixels, convert to the nearest SP token:
| Token | Classic | Studio |
|---|---|---|
SP1 | 6px | 4px |
SP2 | 12px | 8px |
SP3 | 18px | 12px |
SP4 | 24px | 16px |
SP5 | 30px | 20px |
SP6 | 36px | 24px |
<Box gap="SP2" padding="SP3">Only use SP tokens for gap, padding, margin — not for width/height.
Imports
import { Button, Card, Image } from "@wix/design-system";
import { Add, Edit, Delete } from "@wix/wix-ui-icons-common";GUIDELINES
Don't ever override WDS CSS tokens. Only if it's not possible otherwise, mention that very clearly to the prompter, that this is an anti-pattern and should be avoided at all costs.
Troubleshooting
Components render unstyled (plain HTML look, missing WDS spacing/typography): add
import "@wix/design-system/styles.global.css";once to the root/main component (e.g.page.tsx, modal entry) — not child/tab/helper files.
Files
- ATTRIBUTION.mdAdded by AutoGineer821 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md5.6 KiB
- references/file-structure.md1.1 KiB
- scripts/wds.cjsScript15.1 KiB
scripts/wds.cjs
#!/usr/bin/env node
/**
* WDS Documentation Helper
*
* Auto-discovers @wix/design-system in node_modules and provides
* fast, focused lookups for components, props, examples, and icons.
*
* Usage:
* node <path-to>/wds.cjs search <keyword>
* node <path-to>/wds.cjs component <Name>
* node <path-to>/wds.cjs components <Name1> <Name2>...
* node <path-to>/wds.cjs example <Name> <ExampleName>
* node <path-to>/wds.cjs testkit <Name> [method]
* node <path-to>/wds.cjs icons <query>
*/
const fs = require("fs");
const path = require("path");
// ---------------------------------------------------------------------------
// Path discovery
// ---------------------------------------------------------------------------
function tryEnablePnp() {
// Yarn Berry PnP projects have no node_modules. Walk up from cwd looking for
// .pnp.cjs and activate it so require.resolve can see PnP-managed packages.
let dir = process.cwd();
while (true) {
const pnp = path.join(dir, ".pnp.cjs");
if (fs.existsSync(pnp)) {
try {
require(pnp).setup();
} catch {
// ignore — fall through to other discovery paths
}
return;
}
const parent = path.dirname(dir);
if (parent === dir) return;
dir = parent;
}
}
function findDocsDir() {
tryEnablePnp();
// Primary: use Node's module resolver (handles symlinks, pnpm, yarn PnP, etc.)
try {
const pkgPath = require.resolve("@wix/design-system/package.json", {
paths: [process.cwd()],
});
const docsDir = path.join(path.dirname(pkgPath), "dist", "docs");
if (fs.existsSync(docsDir)) return docsDir;
} catch {
// resolve failed — fall through to filesystem scan
}
// Fallback: walk up from cwd looking for node_modules
let dir = process.cwd();
while (true) {
const candidate = path.join(
dir,
"node_modules",
"@wix",
"design-system",
"dist",
"docs"
);
if (fs.existsSync(candidate)) return candidate;
const parent = path.dirname(dir);
if (parent === dir) break;
dir = parent;
}
return null;
}
function readFile(filePath) {
try {
return fs.readFileSync(filePath, "utf8");
} catch {
return null;
}
}
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
function escapeRegex(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function buildTermsPattern(args) {
// Tolerate both `search foo bar` (separate args) and `search "foo bar"`
// (single quoted arg). Without the split, a single quoted string becomes a
// literal-phrase match instead of OR-of-words and silently returns nothing.
return args
.flatMap((a) => a.split(/\s+/))
.filter(Boolean)
.map(escapeRegex)
.join("|");
}
function validateComponentName(name) {
if (!/^[A-Za-z0-9]+$/.test(name)) {
console.error(
`Invalid component name "${name}". Names may only contain letters and digits.`
);
process.exit(1);
}
}
// ---------------------------------------------------------------------------
// Commands
// ---------------------------------------------------------------------------
function cmdSearch(docsDir, terms) {
if (terms.length === 0) {
console.error("Usage: wds.cjs search <keyword> [keyword...]");
console.error('Example: wds.cjs search form input validation');
process.exit(1);
}
const content = readFile(path.join(docsDir, "components.md"));
if (!content) {
console.error("Error: components.md not found");
process.exit(1);
}
const regex = new RegExp(buildTermsPattern(terms), "i");
const sections = content.split(/^\s*### /m).slice(1);
const matches = [];
for (const section of sections) {
if (regex.test(section)) {
const lines = section.split("\n");
const name = lines[0].trim();
const descLine = lines.find((l) => l.trimStart().startsWith("- description:"));
const desc = descLine ? descLine.replace(/.*- description:/, "").trim() : "";
const doLine = lines.find((l) => l.trimStart().startsWith("- do:"));
const doText = doLine ? doLine.replace(/.*- do:/, "").trim() : "";
const dontLine = lines.find((l) => l.trimStart().startsWith("- donts:"));
const dontText = dontLine ? dontLine.replace(/.*- donts:/, "").trim() : "";
matches.push({ name, description: desc, do: doText, donts: dontText });
}
}
if (matches.length === 0) {
console.log(`No components found matching "${terms.join(" ")}".`);
return;
}
console.log(`Found ${matches.length} component(s):\n`);
for (const r of matches) {
console.log(`### ${r.name}`);
if (r.description) console.log(` ${r.description}`);
if (r.do) console.log(` Do: ${r.do}`);
if (r.donts) console.log(` Don't: ${r.donts}`);
console.log();
}
}
// Renders one component's props + examples list. Returns true on success,
// false if the component wasn't found (so batch callers can keep going).
function printComponent(docsDir, componentName) {
validateComponentName(componentName);
const componentsDir = path.join(docsDir, "components");
// --- Props ---
const propsPath = path.join(componentsDir, `${componentName}Props.md`);
const propsContent = readFile(propsPath);
if (!propsContent) {
console.error(
`Component "${componentName}" not found. Run: wds.cjs search <keyword>`
);
return false;
}
const propsLines = propsContent.split("\n");
const propsLineCount = propsLines.length;
console.log(`## ${componentName} Props (${propsLineCount} lines)\n`);
if (propsLineCount <= 200) {
// Small file — include full props
console.log(propsContent);
} else {
// Large file — summarize prop names and types only
console.log(
`(Large props file — showing summary. Use grep for specific prop details.)\n`
);
for (const line of propsLines) {
if (line.startsWith("### ")) {
const propName = line.replace("### ", "").trim();
// Find the type line (next line starting with "- type:")
const idx = propsLines.indexOf(line);
const typeLine = propsLines[idx + 1];
const type =
typeLine && typeLine.startsWith("- type:")
? typeLine.replace("- type:", "").trim()
: "";
console.log(` ${propName}: ${type}`);
}
}
}
// --- Examples list ---
const examplesPath = path.join(componentsDir, `${componentName}Examples.md`);
const examplesContent = readFile(examplesPath);
if (examplesContent) {
const exLines = examplesContent.split("\n");
const examples = [];
for (let i = 0; i < exLines.length; i++) {
if (exLines[i].startsWith("### ")) {
examples.push(exLines[i].replace("### ", "").trim());
}
}
if (examples.length > 0) {
console.log(`\n## Available Examples (${examples.length})\n`);
for (const ex of examples) {
console.log(` - ${ex}`);
}
console.log(
`\nGet an example: wds.cjs example ${componentName} "<ExampleName>"`
);
}
}
return true;
}
function cmdComponent(docsDir, componentName) {
if (!componentName) {
console.error("Usage: wds.cjs component <ComponentName>");
console.error("Example: wds.cjs component Button");
process.exit(1);
}
if (!printComponent(docsDir, componentName)) {
process.exit(1);
}
}
// Cheap pre-check so cmdComponents can decide whether to emit a `---`
// separator before invoking the actual renderer. Avoids stale separators
// when a middle component is missing.
function componentExists(docsDir, componentName) {
if (!/^[A-Za-z0-9]+$/.test(componentName)) return false;
return fs.existsSync(
path.join(docsDir, "components", `${componentName}Props.md`)
);
}
function cmdComponents(docsDir, args) {
// Accept either `components Button Card` or `components "Button Card"`.
const names = args.flatMap((a) => a.split(/\s+/)).filter(Boolean);
if (names.length === 0) {
console.error("Usage: wds.cjs components <Name1> [Name2] [Name3]...");
console.error("Example: wds.cjs components Button Card Table");
process.exit(1);
}
let printedAny = false;
let anyFailed = false;
for (const name of names) {
// Match the single-component flow: invalid names get a distinct error
// instead of being lumped under "not found".
if (!/^[A-Za-z0-9]+$/.test(name)) {
console.error(
`Invalid component name "${name}". Names may only contain letters and digits.`
);
anyFailed = true;
continue;
}
if (!componentExists(docsDir, name)) {
console.error(
`Component "${name}" not found. Run: wds.cjs search <keyword>`
);
anyFailed = true;
continue;
}
if (printedAny) console.log("\n---\n");
printComponent(docsDir, name);
printedAny = true;
}
// Exit non-zero only if every requested component failed.
if (anyFailed && !printedAny) process.exit(1);
}
function cmdExample(docsDir, componentName, exampleName) {
if (!componentName || !exampleName) {
console.error('Usage: wds.cjs example <ComponentName> "<ExampleName>"');
console.error('Example: wds.cjs example Button "Loading state"');
process.exit(1);
}
validateComponentName(componentName);
const filePath = path.join(
docsDir,
"components",
`${componentName}Examples.md`
);
const content = readFile(filePath);
if (!content) {
console.error(`No examples file for "${componentName}".`);
process.exit(1);
}
const lines = content.split("\n");
let startLine = -1;
let endLine = lines.length;
const searchName = exampleName.toLowerCase();
for (let i = 0; i < lines.length; i++) {
if (lines[i].startsWith("### ")) {
const name = lines[i].replace("### ", "").trim().toLowerCase();
if (startLine >= 0) {
// Found the next section — stop here
endLine = i;
break;
}
if (name === searchName || name.includes(searchName)) {
startLine = i;
}
}
}
if (startLine < 0) {
console.error(
`Example "${exampleName}" not found for ${componentName}.\n`
);
// List available examples
const available = [];
for (const line of lines) {
if (line.startsWith("### ")) {
available.push(line.replace("### ", "").trim());
}
}
if (available.length > 0) {
console.log("Available examples:");
for (const ex of available) {
console.log(` - ${ex}`);
}
}
process.exit(1);
}
console.log(lines.slice(startLine, endLine).join("\n"));
}
function cmdTestkit(docsDir, componentName, methodName) {
if (!componentName) {
console.error("Usage: wds.cjs testkit <ComponentName> [methodName]");
console.error("Example: wds.cjs testkit Button");
console.error('Example: wds.cjs testkit Button click');
process.exit(1);
}
validateComponentName(componentName);
const filePath = path.join(
docsDir,
"components",
`${componentName}Testkit.md`,
);
const content = readFile(filePath);
if (!content) {
console.error(
`Testkit docs for "${componentName}" not found. Run: wds.cjs search <keyword>`,
);
process.exit(1);
}
if (!methodName) {
console.log(content);
return;
}
const lines = content.split("\n");
const searchName = methodName.toLowerCase();
let startLine = -1;
let endLine = lines.length;
for (let i = 0; i < lines.length; i++) {
if (lines[i].startsWith("### ") && !lines[i].startsWith("### API")) {
const name = lines[i].replace("### ", "").trim().toLowerCase();
if (startLine >= 0) {
endLine = i;
break;
}
if (name === searchName || name.includes(searchName)) {
startLine = i;
}
}
}
if (startLine < 0) {
console.error(
`Method "${methodName}" not found on ${componentName} testkit.\n`,
);
const available = [];
let inApiSection = false;
for (const line of lines) {
if (line.startsWith("### API")) {
inApiSection = true;
continue;
}
if (inApiSection && line.startsWith("### ")) {
available.push(line.replace("### ", "").trim());
}
}
if (available.length > 0) {
console.log("Available methods:");
for (const m of available) {
console.log(` - ${m}`);
}
}
process.exit(1);
}
console.log(lines.slice(startLine, endLine).join("\n"));
}
function cmdIcons(docsDir, terms) {
if (terms.length === 0) {
console.error("Usage: wds.cjs icons <query> [query...]");
console.error("Example: wds.cjs icons Add Edit Delete");
process.exit(1);
}
const content = readFile(path.join(docsDir, "icons.md"));
if (!content) {
console.error("Error: icons.md not found");
process.exit(1);
}
const regex = new RegExp(buildTermsPattern(terms), "i");
const matches = [];
for (const line of content.split("\n")) {
if (line.trim() && regex.test(line)) {
matches.push(line.trim());
}
}
if (matches.length === 0) {
console.log(`No icons found matching "${terms.join(" ")}".`);
return;
}
console.log(`Found ${matches.length} icon(s):\n`);
for (const m of matches) {
console.log(` ${m}`);
}
console.log(
"\nIcons are from @wix/wix-ui-icons-common. Each icon has a Small variant (e.g., Add + AddSmall)."
);
}
function cmdHelp(docsDir) {
const scriptPath = path.resolve(__dirname, "wds.cjs");
console.log(`WDS Documentation Helper
Usage:
node ${scriptPath} search <keyword> Search components by keyword
node ${scriptPath} component <Name> Get props + example list
node ${scriptPath} components <Name1> <Name2>... Get props + example list for multiple components in one call
node ${scriptPath} example <Name> "<ExampleName>" Get a specific example
node ${scriptPath} testkit <Name> [method] Get testkit imports + API (or one method)
node ${scriptPath} icons <query> Search for icons
Examples:
node ${scriptPath} search table list
node ${scriptPath} search form input validation
node ${scriptPath} component Button
node ${scriptPath} components Button Card Table Input
node ${scriptPath} example Button "Loading state"
node ${scriptPath} testkit Button
node ${scriptPath} testkit Button click
node ${scriptPath} icons Add Edit Delete
Docs found at: ${docsDir}`);
}
// ---------------------------------------------------------------------------
// Main
// ---------------------------------------------------------------------------
const docsDir = findDocsDir();
if (!docsDir) {
console.error(
"Error: @wix/design-system not found in node_modules.\n" +
"Install it first: npm i @wix/design-system"
);
process.exit(1);
}
const [command, ...args] = process.argv.slice(2);
switch (command) {
case "search":
cmdSearch(docsDir, args);
break;
case "component":
cmdComponent(docsDir, args[0]);
break;
case "components":
cmdComponents(docsDir, args);
break;
case "example":
cmdExample(docsDir, args[0], args.slice(1).join(" "));
break;
case "testkit":
cmdTestkit(docsDir, args[0], args[1]);
break;
case "icons":
cmdIcons(docsDir, args);
break;
default:
cmdHelp(docsDir);
break;
}
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Node.js
Security
What our scanner noticed· Low risk
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Wix
- Publisher
- Wix (Official)
- Source
- wix/skills · skills/wix-design-system · commit d168bc2
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Wix.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download wix-design-system.zip