# Migrating to 15.0.0

This release contains significant or breaking changes.

## Significant changes

Two significant changes may affect you:

- deprecated stylistic rules
- added the `declaration-property-value-no-unknown` rule

### Deprecated stylistic rules

We've deprecated 76 of the rules that enforce stylistic conventions:

- `at-rule-name-case`
- `at-rule-name-newline-after`
- `at-rule-name-space-after`
- `at-rule-semicolon-newline-after`
- `at-rule-semicolon-space-before`
- `block-closing-brace-empty-line-before`
- `block-closing-brace-newline-after`
- `block-closing-brace-newline-before`
- `block-closing-brace-space-after`
- `block-closing-brace-space-before`
- `block-opening-brace-newline-after`
- `block-opening-brace-newline-before`
- `block-opening-brace-space-after`
- `block-opening-brace-space-before`
- `color-hex-case`
- `declaration-bang-space-after`
- `declaration-bang-space-before`
- `declaration-block-semicolon-newline-after`
- `declaration-block-semicolon-newline-before`
- `declaration-block-semicolon-space-after`
- `declaration-block-semicolon-space-before`
- `declaration-block-trailing-semicolon`
- `declaration-colon-newline-after`
- `declaration-colon-space-after`
- `declaration-colon-space-before`
- `function-comma-newline-after`
- `function-comma-newline-before`
- `function-comma-space-after`
- `function-comma-space-before`
- `function-max-empty-lines`
- `function-parentheses-newline-inside`
- `function-parentheses-space-inside`
- `function-whitespace-after`
- `indentation`
- `linebreaks`
- `max-empty-lines`
- `max-line-length`
- `media-feature-colon-space-after`
- `media-feature-colon-space-before`
- `media-feature-name-case`
- `media-feature-parentheses-space-inside`
- `media-feature-range-operator-space-after`
- `media-feature-range-operator-space-before`
- `media-query-list-comma-newline-after`
- `media-query-list-comma-newline-before`
- `media-query-list-comma-space-after`
- `media-query-list-comma-space-before`
- `no-empty-first-line`
- `no-eol-whitespace`
- `no-extra-semicolons`
- `no-missing-end-of-source-newline`
- `number-leading-zero`
- `number-no-trailing-zeros`
- `property-case`
- `selector-attribute-brackets-space-inside`
- `selector-attribute-operator-space-after`
- `selector-attribute-operator-space-before`
- `selector-combinator-space-after`
- `selector-combinator-space-before`
- `selector-descendant-combinator-no-non-space`
- `selector-list-comma-newline-after`
- `selector-list-comma-newline-before`
- `selector-list-comma-space-after`
- `selector-list-comma-space-before`
- `selector-max-empty-lines`
- `selector-pseudo-class-case`
- `selector-pseudo-class-parentheses-space-inside`
- `selector-pseudo-element-case`
- `string-quotes`
- `unicode-bom`
- `unit-case`
- `value-list-comma-newline-after`
- `value-list-comma-newline-before`
- `value-list-comma-space-after`
- `value-list-comma-space-before`
- `value-list-max-empty-lines`

When we created these rules, pretty printers (like [Prettier](https://prettier.io/)) didn't exist. They now offer a better way to consistently format code, especially whitespace. Linters and pretty printers are complementary tools that work together to help you write consistent and error-free code.

By deprecating these rules, we can:

- focus on writing and maintaining rules that help you [avoid errors](../user-guide/rules.md#avoid-errors) and [enforce (non-stylistic) conventions](../user-guide/rules.md#enforce-conventions), both of which are unique to Stylelint
- modernize our codebase, e.g. move to ESM so that we can update our dependencies and keep Stylelint secure for you

The deprecated rules will still work in this release (with a deprecation warning). In preparation for the next major release, when we'll remove the rules from Stylelint, we suggest:

- extending the [standard config](https://www.npmjs.com/package/stylelint-config-standard) in your configuration object, if you don't already
- removing the deprecated rules from your configuration object

You can [extend](../user-guide/configure.md#extends) the [standard config](https://www.npmjs.com/package/stylelint-config-standard) using:

```diff json
{
+ "extends": ["stylelint-config-standard"],
  "rules": { .. }
}
```

Additionally, you may no longer need to extend [Prettier's Stylelint config](https://www.npmjs.com/package/stylelint-config-prettier) as there should be no conflicting rules:

```diff json
{
- "extends": ["stylelint-config-prettier"],
  "rules": { .. }
}
```

We've removed the deprecated rules from the latest version of the [standard config](https://www.npmjs.com/package/stylelint-config-standard). It still helps you write consistent CSS by turning on many of the [other rules that enforce conventions](../user-guide/rules.md#enforce-conventions), e.g. most of the [`*-notation`](../user-guide/rules.md#notation), [`*-pattern`](../user-guide/rules.md#pattern) and [`*-quotes`](../user-guide/rules.md#quotes) rules.

There are lots of other rules we don't turn on in the [standard config](https://www.npmjs.com/package/stylelint-config-standard) and you can learn more about using them to customize Stylelint to your exact needs in our [new guide](../user-guide/customize.md).

Alternatively, you can continue to enforce stylistic consistency with Stylelint by using the community plugin [`@stylistic/stylelint-plugin`](https://www.npmjs.com/package/@stylistic/stylelint-plugin) that has migrated the deprecated rules.

You can use the [`quietDeprecationWarnings`](../user-guide/options.md#quietdeprecationwarnings) option to silence the deprecation warnings.

### Added `declaration-property-value-no-unknown` rule

We added the [`declaration-property-value-no-unknown`](../../lib/rules/declaration-property-value-no-unknown/README.md) rule. It will flag property-value pairs that are unknown in the CSS specifications, for example:

```css
a {
  top: red;
}
```

The `top` property accepts either a `<length>`, `<percentage>` or the `auto` keyword. The rule will flag `red` as it's a `<color>`.

Many of you have requested this rule, and we plan to add more like it to help you [avoid errors](../user-guide/rules.md#avoid-errors) in your CSS.

To turn it on in your configuration object:

```diff json
{
  "extends": ["stylelint-config-standard"],
  "rules": {
+   "declaration-property-value-no-unknown": true
    ..
   }
}
```

The rule uses [CSSTree](https://github.com/csstree/csstree) and its [syntax dictionary](https://csstree.github.io/docs/syntax/) of 600+ properties, 350+ types and 100+ functions. You can help identify and plug any gaps in its dictionary by either updating [mdn-data](https://github.com/mdn/data/) or [CSSTree's patch file](https://github.com/csstree/csstree/blob/master/data/patch.json).

If you use values that aren't in the CSS specifications, you can use the rule's secondary options to make the rule more permissive. You can either:

- ignore properties or values outright
- extend the properties and values syntaxes

The latter ensures only specific exceptions are allowed.

If you currently use the [`stylelint-csstree-validator`](https://www.npmjs.com/package/stylelint-csstree-validator) plugin, you can continue to use it alongside the new rule by limiting the plugin to check only at-rule names and preludes.

```diff json
{
  "rules": {
    "csstree/validator": [true, {
+      "ignoreProperties": ["/.+/"]
    }]
  }
}
```

## Breaking changes

Three breaking changes may also affect you:

- removed `processors` configuration property
- removed support for Node.js 12
- changed `overrides.extends` behavior

### Removed `processors` configuration property

Processors were our first attempt to support containers of CSS, e.g. Markdown, HTML and CSS-in-JS. We later introduced [custom syntaxes](../developer-guide/syntaxes.md) to fix some of the shortcomings of processors, e.g. incompatibility with the [`--fix` option](../user-guide/options.md#fix).

We've also deprecated the [`postcss-css-in-js`](https://www.npmjs.com/package/@stylelint/postcss-css-in-js) custom syntax. It was not possible to maintain a monolithic custom syntax that attempted to support every CSS-in-JS library and syntax, as there are so many of them and each with variations in syntax.

You should remove the `processors` property from your configuration object and use a library-specific or syntax-specific (e.g. template literals) [custom syntax](../user-guide/options.md#customsyntax) instead.

For example, if you use [styled-components](https://styled-components.com):

```diff json
{
- "processors": ["stylelint-processor-styled-components"],
+ "customSyntax": "postcss-styled-syntax",
  "rules": { .. }
}
```

Other custom syntaxes include:

- [postcss-html](https://www.npmjs.com/package/postcss-html)
- [postcss-linaria](https://www.npmjs.com/package/@linaria/postcss-linaria)
- [postcss-lit](https://www.npmjs.com/package/postcss-lit)
- [postcss-markdown](https://www.npmjs.com/package/postcss-markdown)

You'll find a complete list of them in [Awesome Stylelint](https://github.com/stylelint/awesome-stylelint#readme).

If you create a new custom syntax, please [open a pull request](https://github.com/stylelint/awesome-stylelint/compare) to update [Awesome Stylelint](https://github.com/stylelint/awesome-stylelint#readme) so that others can find it. For example, [Stitches](https://stitches.dev/) and [vanilla-extract](https://vanilla-extract.style/) need syntaxes, which are object-based CSS-in-JS libraries.

### Removed support for Node.js 12

Node.js 12 has reached end-of-life. We've removed support for it so that we could update some of our dependencies. You should use the following or higher versions of Node.js:

- 14.13.1
- 16.0.0
- 18.0.0

### Changed `overrides.extends` behavior

To be consistent with the `overrides.plugins`, we've changed the behaviour of `overrides.extends` to merge rather than replace.

If you would like to keep the previous behavior, you should change your config to:

```diff json
{
- "extends": ["config-a"],
  "overrides": [
    {
      "files": ["*.module.css"],
      "extends": ["config-b"]
    },
+   {
+     "files": ["*.css"],
+     "extends": ["config-a"]
+   }
  ]
}
```
