Generated banner for Wix Design System
Generated logo for Wix Design System

Wix Design System

WixOfficialPublished by Wix

  • Skill
  • Tool integration
  • Software development
  • MIT
  • Low risk
  • Has scripts

From the author

Wix Design System component reference. Use when building UI with @wix/design-system, choosing components, checking props and examples, or writing tests with component testkits. Triggers on "what component", "how do I make", "WDS", "show me props", "testkit", "driver", or component names like Button, Card, Modal, Box, Text.
— the description by Wix

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

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/wix/wix-design-system/download
  2. Unzip 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 icons

Workflow

Step 1: Find the right component
node $WDS search table
node $WDS search form input validation
node $WDS search modal dialog popup

Multiple keywords are OR-matched. Returns component names, descriptions, and usage guidance.

Step 2: Get props and available examples
node $WDS component Button

Returns 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 Thumbnail

Output 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 details

Returns 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 Delete

Icons 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 component

  • components/{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 ElementWDS ComponentNotes
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:

TokenClassicStudio
SP16px4px
SP212px8px
SP318px12px
SP424px16px
SP530px20px
SP636px24px
<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

  1. 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

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 or Wix.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download wix-design-system.zip