How to Configure Active Linting Rules in DESIGN.md

The DESIGN.md CLI exposes active linting rules through the spec command with --rules or --rules-only flags, while the rule definitions are centrally managed in packages/cli/src/linter/linter/rules/index.ts.

DESIGN.md is a structured documentation format for design systems that includes built-in validation through its CLI tool. Understanding how to configure and view active linting rules helps you validate your design documents against the correct rule set and troubleshoot validation failures.

Where Active Linting Rules Are Defined

The DESIGN.md linter maintains its rule configuration in a centralized location within the CLI package. These rules are consumed by both the lint command and the spec command.

Rule Descriptors Array

The canonical list of active rules lives in packages/cli/src/linter/linter/rules/index.ts. This file exports DEFAULT_RULE_DESCRIPTORS, an ordered array containing rule metadata:

// packages/cli/src/linter/linter/rules/index.ts
export const DEFAULT_RULE_DESCRIPTORS: RuleDescriptor[] = [
  brokenRefRule,
  missingPrimaryRule,
  contrastCheckRule,
  orphanedTokensRule,
  tokenSummaryRule,
  missingSectionsRule,
  missingTypographyRule,
  sectionOrderRule,
  unknownKeyRule,
  tokenLikeIgnoredRule,
];

Each descriptor object contains the rule name, severity level, and description used when generating reports and documentation.

Default Rules Implementation

The linter converts these descriptors into executable functions via the toLintRule mapper:

export const DEFAULT_RULES: LintRule[] = DEFAULT_RULE_DESCRIPTORS.map(toLintRule);

This DEFAULT_RULES array is what the lint command executes when validating DESIGN.md files. If you invoke the linter programmatically without specifying a custom rule set, it automatically uses this default array.

Viewing Active Linting Rules via CLI

The spec command provides multiple ways to inspect the currently configured rule set without reading the source code directly.

Markdown Output Options

Use these flags to generate human-readable rule documentation:

  • --rules-only: Outputs exclusively the linting rules table in Markdown format
  • --rules: Appends the active linting rules table to the full generated specification

# Display only the rules table

design spec --rules-only

# Generate full spec with rules appendix

design spec --rules

According to the implementation in packages/cli/src/commands/spec.ts, the command generates the rules table using getRulesTable(DEFAULT_RULE_DESCRIPTORS) and injects it under the heading ## Active Linting Rules when using the --rules flag.

JSON Output Options

For programmatic consumption, combine the rules flags with --format json:


# JSON payload containing only rules

design spec --rules-only --format json

# JSON payload with both spec content and rules array

design spec --rules --format json

The JSON output structure maps each rule descriptor to an object containing name, severity, and description properties, ensuring your automation scripts can parse rule configurations reliably.

Customizing the Rule Set (Advanced)

While the CLI does not expose a configuration flag for modifying the default rule set, you can configure active linting rules programmatically by importing the linter directly.

Create a custom script that imports the base rules and extends or filters them:

// Example: Programmatic usage with a custom rule set
import { lint, DEFAULT_RULES } from '@design/cli';
import { myExtraRule } from './my-rules';

const content = await readFile('my-design.md', 'utf8');
const report = lint(content, { rules: [...DEFAULT_RULES, myExtraRule] });
console.log(report.findings);

This approach allows you to:

  • Add custom rules by spreading DEFAULT_RULES and appending your own LintRule implementations
  • Disable specific rules by filtering the DEFAULT_RULES array before passing it to the lint function
  • Modify severity by mapping over the default rules and adjusting their properties

Summary

  • Active linting rules are defined in packages/cli/src/linter/linter/rules/index.ts as DEFAULT_RULE_DESCRIPTORS and compiled into DEFAULT_RULES
  • View current rules using design spec --rules-only for Markdown or design spec --rules-only --format json for JSON
  • Embed rules in specs by appending --rules to the spec command
  • Customize rules by importing @design/cli and passing a modified rules array to the lint() function programmatically

Frequently Asked Questions

How do I see what linting rules are currently active?

Run design spec --rules-only to display a Markdown table of all active rules, including their names, severity levels, and descriptions. For machine-readable output, use design spec --rules-only --format json.

Can I disable specific linting rules in the CLI?

The CLI does not currently support disabling individual rules via command-line flags. To customize the rule set, you must use the programmatic API by importing { lint, DEFAULT_RULES } from @design/cli and filtering the array before passing it to the lint function.

Where are the linting rule severity levels defined?

Severity levels are defined within each rule descriptor in packages/cli/src/linter/linter/rules/index.ts. Each entry in the DEFAULT_RULE_DESCRIPTORS array is a RuleDescriptor object that includes a severity property (typically "error" or "warning") that determines how the linter reports violations.

How do I add custom linting rules to DESIGN.md?

Create a custom Node.js script that imports the lint function and DEFAULT_RULES from @design/cli, then pass a modified rules array that includes your custom LintRule implementations. The CLI does not support loading external rule files natively, so this requires programmatic integration.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →