Skip to content

Stylelint Plugin

A Stylelint plugin that validates SpiraCSS design rules in SCSS files.
Designed to be used with the SpiraCSS Design Principles.

Install

Stylelint v17 or later is required. Node.js >= 20.19.0 is required.

Stylelint v16 users: use @spiracss/stylelint-plugin@0.3.x.

Terminal window
yarn add -D @spiracss/stylelint-plugin stylelint stylelint-scss postcss-scss
Terminal window
npm install -D @spiracss/stylelint-plugin stylelint stylelint-scss postcss-scss

Rules

RuleDescription
spiracss/class-structureNaming, parent-child structure, section structure
spiracss/property-placementProperty placement (container / item / internal)
spiracss/page-layerPage entry SCSS boundaries and component links
spiracss/interaction-scopeInteraction section placement and structure
spiracss/interaction-propertiesTransition / animation usage inside interaction
spiracss/keyframes-naming@keyframes placement and naming
spiracss/pseudo-nestingPseudo-class / pseudo-element nesting
spiracss/rel-comments@rel comments for parent-child links

For rule details (✅ / ❌ examples), see the rule pages.

Configuration

This plugin reads spiracss.config.js at the project root.
Use createRules() or createRulesAsync() to generate rule settings from the config.

Passing config object directly

stylelint.config.js
import spiracssPlugin, { createRules } from '@spiracss/stylelint-plugin'
import spiracssConfig from './spiracss.config.js'
export default {
plugins: [...spiracssPlugin, 'stylelint-scss'],
customSyntax: 'postcss-scss',
// Exclude shared partials; keep shared keyframes linted.
ignoreFiles: ['src/styles/partials/**/*.scss', '!src/styles/partials/keyframes.scss'],
rules: {
...createRules(spiracssConfig),
'scss/at-rule-no-unknown': true
}
}

Path-based loading

If you need path-based loading, use createRulesAsync().

stylelint.config.js
import spiracssPlugin, { createRulesAsync } from '@spiracss/stylelint-plugin'
const rules = await createRulesAsync('./spiracss.config.js')
export default {
plugins: [...spiracssPlugin, 'stylelint-scss'],
customSyntax: 'postcss-scss',
// Exclude shared partials; keep shared keyframes linted.
ignoreFiles: ['src/styles/partials/**/*.scss', '!src/styles/partials/keyframes.scss'],
rules: {
...rules,
'scss/at-rule-no-unknown': true
}
}

Note: aliasRoots is required when using createRules() or createRulesAsync().

Disabling rules

There are two ways to disable or relax rules:

  1. Stylelint config: set a rule to null (always works).
// Using the same imports as the examples above
export default {
rules: {
...createRules(spiracssConfig),
'spiracss/rel-comments': null // disable this rule
}
}
  1. spiracss.config.js: set stylelint.<rule>.enabled = false or adjust rule options (only when using createRules() / createRulesAsync()).
spiracss.config.js
export default {
stylelint: {
keyframes: { enabled: false },
pseudo: { enabled: false },
rel: { requireChild: false }
}
}

For detailed options, see Configuration Options.

Limitations

  • Validates structural elements (class names, selector structure, @rel comments)
  • Some rules intentionally prioritize “mechanically verifiable” over “interpretive” (e.g. spiracss/property-placement sizeInternal)
  • Cannot automatically judge design decisions (Element chain intent, data/state validity)
  • Supplement with design reviews or code reviews

Recommended setup: stylelint-config-standard-scss + stylelint-config-recess-order.
The recommended config for that setup is documented in Tips.