Skip to content

Stylelint (SCSS) ​

Biome does not support SCSS, so generated projects use Stylelint for SCSS linting. The two tools cover separate file types and do not overlap.

Configuration ​

The generated .stylelintrc:

json
{
    "plugins": [
        "stylelint-scss",
        "stylelint-order"
    ],
    "rules": {
        "block-no-empty": true,
        "number-no-trailing-zeros": true,
        "max-empty-lines": 1,
        "color-no-invalid-hex": true,
        "declaration-block-single-line-max-declarations": 1,
        "function-url-quotes": "always",
        "no-missing-end-of-source-newline": true,
        "string-quotes": "single",
        "selector-max-id": 1,
        "max-nesting-depth": 4,
        "scss/dollar-variable-pattern": "^_?[a-z]+[\\w-]*$",
        "scss/at-extend-no-missing-placeholder": true,
        "scss/dollar-variable-colon-space-before": "never",
        "scss/dollar-variable-colon-space-after": "always",
        "scss/selector-no-redundant-nesting-selector": true,
        "order/order": [
            "declarations",
            "rules"
        ]
    }
}

Rules explained ​

General rules ​

RuleValueMeaning
block-no-emptytrueNo empty {} blocks
number-no-trailing-zerostrue0.5 not 0.50
max-empty-lines1At most one blank line between declarations
color-no-invalid-hextrueValidates hex colour values
declaration-block-single-line-max-declarations1One declaration per line — no { color: red; margin: 0 }
function-url-quotes'always'url('...') not url(...)
no-missing-end-of-source-newlinetrueFiles must end with a newline
string-quotes'single'Single quotes — consistent with Biome JS formatter
selector-max-id1At most one ID selector per rule
max-nesting-depth4Maximum SCSS nesting depth

SCSS-specific rules (stylelint-scss) ​

RuleMeaning
scss/dollar-variable-patternVariable names must be camelCase or kebab-case
scss/at-extend-no-missing-placeholder@extend must target a %placeholder, not a class
scss/dollar-variable-colon-space-before: never$var: value not $var : value
scss/dollar-variable-colon-space-after: always$var: value not $var:value
scss/selector-no-redundant-nesting-selectorNo & .child when .child would suffice

Property ordering (stylelint-order) ​

Declarations must come before nested rules:

scss
// CORRECT
.card {
    display: flex;          // declarations first
    padding: 1rem;

    &:hover {               // nested rules after
        opacity: 0.8;
    }
}

// WRONG — nested rule before declaration
.card {
    &:hover {
        opacity: 0.8;
    }
    display: flex;          // declaration after nested rule
}

CSS Modules convention ​

Generated projects use Vite's CSS Modules. Class names in SCSS files are scoped automatically:

scss
// styles.module.scss
.cardWrapper {
    display: flex;
}
jsx
// index.jsx
import style from './styles.module.scss';

<div class={style.cardWrapper}>...</div>

Use camelCase for CSS Module class names — the Vite config is set to localsConvention: 'camelCase'.

Internal tool — Samsung / Sogody experimentation team