stylelint-scss: the SCSS rules Stylelint deliberately leaves out
A collection of SCSS specific linting rules for Stylelint
At a glance
- What is it?
- stylelint-scss is a plugin that adds SCSS-specific rules to Stylelint, covering the parts of the language that plain CSS linting has no opinion about: mixin and function call conventions, at-rule syntax, dollar variables and nesting pitfalls. It is maintained as part of a family that also ships a shared config, and it follows Stylelint's own rule naming conventions.
- Who is it for?
- Use stylelint-scss when you lint SCSS and want the language's own conventions enforced rather than left to review, since the plugin covers the call and naming conventions that plain CSS rules cannot see and most of its rules can autofix. Do not install it directly unless you are building a config from scratch, because the project recommends the stylelint-config-standard-scss shared config instead, which is where the rules are curated together.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Stylelint covers and what it leaves to this plugin
The README is explicit about the division of labour. Stylelint by itself supports SCSS syntax very well, along with other preprocessor syntaxes, and it introduces some rules that can be used to lint SCSS, for example to limit nesting or to control the way at-rules are written. Yet the general focus of Stylelint is standard CSS. stylelint-scss introduces the rules that are specific to SCSS syntax. The interesting consequence follows from that: the rules from this plugin can be used with other syntaxes such as Less or some PostCSS syntaxes, which is why the rule names are not tied to SCSS only. The example given is at-function-pattern rather than scss-function-pattern. That is a deliberate naming decision, since the rules describe the Sass-like constructs they operate on rather than the file extension they usually appear in, and it keeps the plugin usable for a project that has both SCSS and Less in the same repository.
Installing the plugin directly when you build a config yourself
The recommended route is not this package. The README says the plugin is used in the stylelint-config-standard-scss shared config and recommends using that shared config rather than installing the plugin directly. If you are crafting a config from the ground up, you install both packages with npm.
npm install stylelint stylelint-scssThen you create or open a .stylelintrc.json file, add stylelint-scss to the plugins array and add the rules you want to the rules list. Every rule from this plugin has to be namespaced with scss.
{
"plugins": ["stylelint-scss"],
"rules": {
// recommended rules
"at-rule-no-unknown": null,
"scss/at-rule-no-unknown": true,
// ...
// any other rules you'd want to change e.g.
"scss/dollar-variable-pattern": "^foo",
"scss/selector-no-redundant-nesting-selector": true
}
}The first two lines are the part people miss. Stylelint's own at-rule-no-unknown rule has to be switched off with null, because it does not know the SCSS at-rules, and the plugin's replacement is enabled in its place. Doing this for each overlapping rule is the fiddly part of hand-assembling a config, and it is exactly the argument for taking the shared config instead.
The rules are grouped by the thing they apply to
The rule list is organised the way Stylelint organises its own, by the construct rather than alphabetically, with a section per at-rule family and a README per rule linked from the entry. The at-each section has a single rule, at-each-key-value-single-line, which catches the pattern of looping over map-keys or map.keys and then pulling the value for that key inside the loop. The at-else family has four rules about whitespace and newlines around the closing brace and the parentheses of @else if, all of them autofixable. The at-extend section has one rule, at-extend-no-missing-placeholder, which disallows @extend without a placeholder, since an @extend with no target silently does nothing. The at-function family covers named arguments in function calls, spacing before the parentheses, and a naming pattern, and the at-if family covers the closing brace spacing plus at-if-no-null, which bans null in a condition.
Mixin and function conventions, including the risky ones
The at-mixin group is the largest part of the practical value, since mixins are where SCSS style diverges most from CSS and where teams most want consistency. There are rules for whether argumentless mixin calls carry parentheses, for requiring named parameters in mixin calls, for spacing before the parentheses, and for a naming pattern for mixin names. The one to look at twice is at-mixin-no-risky-nesting-selector, which disallows risky nesting selectors within a mixin. A mixin that contains a nested selector is one whose output depends on where it is included, so a mixin that nests `&__element` produces different CSS depending on the parent it lands in, and a mixin that contains a bare element selector produces a descendant selector that quietly changes specificity. This is a rule that catches a real bug class rather than a formatting preference, and it is the kind of check that is hard to do by eye in review.
Imports and partials, and the newer at-rule rules
The at-import section carries a pair of rules that work together: at-import-partial-extension-allowed-list and at-import-partial-extension-disallowed-list, each specifying a list of allowed or disallowed file extensions for partial names in @import commands. Because they are two rules rather than one setting, a team can allow one extension while still forbidding the others, which is the shape you want when a project is migrating from the old underscore-prefixed partial convention to explicit extensions. The at-rule section contains at-rule-conditional-no-parentheses, which disallows parentheses in the conditional at-rules if, elsif and while, and at-rule-no-unknown, which the README says should be used instead of Stylelint's own version of the same rule, which is the switchover described above. Beyond the at-rules, the plugin also covers dollar variables and selectors, with dollar-variable-pattern for naming and selector-no-redundant-nesting-selector for catching a nested selector that repeats what the parent already says.
Most rules can fix themselves
The one parenthetical that repeats through the rule list is Autofixable, and it appears on the whitespace and newline rules consistently: the closing-brace newline and space rules for @else and @if, the parentheses space rules for @else if, @function and @mixin, the argumentless mixin call parentheses rule and the conditional at-rule parentheses rule. The rules about semantics are not autofixable, which is the right division. A spacing rule is a mechanical transformation with one correct answer, so a linter can rewrite it. Whether a mixin call should use named arguments, whether a function name matches a pattern, whether an @extend has a placeholder and whether a mixin contains a risky nesting selector are decisions where a fixer would have to guess your intent. The npm package metadata lists known-css-properties as a runtime dependency, which is the mechanism behind the unknown at-rule checking, and the parser stack of postcss-selector-parser, postcss-value-parser and css-tree along with the csstools packages is what lets the rules work on the syntactic level rather than on raw text.
What the package requires and how it is built
The packaging metadata is modern and strict about compatibility. The package is an ES module with the exports field pointing at src/index.js, and the published files list includes only src JavaScript, explicitly excluding the per-rule README files and the test directories. The engines field requires Node 20.19.0 or newer, and the peer dependency is stylelint at ^16.8.2 or ^17.0.0, which means the plugin will refuse to install against a Stylelint outside that range, which is the right behaviour given that Stylelint's plugin API changes between majors. The author is recorded as Krister Kari. The development toolchain shows the project's own standards: Jest 30 with a jest-preset-stylelint and a separate setup file, ESLint 10 with the eslint-config-stylelint config, Prettier, husky and lint-staged for commit hooks, and a Lavamoat setup with allow-scripts and a preinstall-always-fail package, which is a supply-chain guard that blocks install scripts from running unless explicitly allowed. The repository also has an eslint.config.mjs of its own and a docs directory holding example configs for special cases.
Where stylelint-scss is the wrong choice
Four limits apply. It is a linter plugin, not a preprocessor, so it tells you about style after compilation rather than fixing the SCSS itself, and a rule that reports a problem in generated CSS still leaves you to work out which source file produced it. It only knows about SCSS, and even that knowledge is bounded by the Sass features the rules were written for, so a project on the newest module system may find some rules do not match the syntax it uses. The autofixable rules are formatting rules, and autofixing them on a large existing codebase produces a diff nobody asked for unless you stage it carefully, which the husky and lint-staged configuration in this repository is designed around but your own may not be. And the plugin assumes a linting setup exists at all, which is not a given: a team that has never linted its stylesheets will find this a large initial surface, and the shared config the project recommends is the smaller way in.
Editorial conclusion
Use stylelint-scss when you lint SCSS and want the language's own conventions enforced rather than left to review, since the plugin covers the call and naming conventions that plain CSS rules cannot see and most of its rules can autofix. Do not install it directly unless you are building a config from scratch, because the project recommends the stylelint-config-standard-scss shared config instead, which is where the rules are curated together. Verify first that your Stylelint version satisfies the peer dependency of ^16.8.2 or ^17.0.0, that your Node version is 20.19.0 or newer, and that the SCSS version you use is one where the rules behave as documented, since several of them target Sass module-era syntax.
Frequently asked questions
What does stylelint-scss add to Stylelint?
Rules specific to SCSS syntax, covering at-rules, mixin and function calls, dollar variables and nesting. Stylelint itself supports SCSS syntax but focuses on standard CSS, and the plugin's rules can also be used with Less or some PostCSS syntaxes, which is why their names are not prefixed with scss.
How do I install and configure stylelint-scss?
Run npm install stylelint stylelint-scss, then add stylelint-scss to the plugins array in .stylelintrc.json and enable the rules you want under the scss namespace. The project recommends using the stylelint-config-standard-scss shared config instead of installing the plugin directly.
Why do I have to disable at-rule-no-unknown?
Stylelint's own at-rule-no-unknown does not know the SCSS at-rules, so it has to be set to null and replaced by the plugin's scss/at-rule-no-unknown. The README states the plugin's version should be used instead of Stylelint's.
Which stylelint-scss rules can fix themselves?
The whitespace and newline rules are marked Autofixable, covering the closing-brace rules for @else and @if, the parentheses space rules, the argumentless mixin call parentheses rule and the conditional at-rule parentheses rule. The semantic rules, such as the mixin and function naming patterns and the risky nesting selector rule, are not.
What are the requirements for stylelint-scss?
Node 20.19.0 or newer, and Stylelint as a peer dependency at ^16.8.2 or ^17.0.0. The current release is 7.3.0, published on 2026-09-15, and the licence is MIT.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/stylelint-scss-stylelint-scss)Was this useful?