# Recommended

Source: https://plumeria.dev/docs/api-reference/plugins/eslint-plugin





[`@plumeria/eslint-plugin`](https://www.npmjs.com/package/@plumeria/eslint-plugin) is the ESLint plugin for Plumeria.

## Installation [#installation]

<Tabs items="['npm',  'yarn', 'pnpm']">
  <Tab>
    ```sh title="Terminal"
    npm i --save-dev @plumeria/eslint-plugin
    ```
  </Tab>

  <Tab>
    ```sh title="Terminal"
    yarn add -D @plumeria/eslint-plugin
    ```
  </Tab>

  <Tab>
    ```sh title="Terminal"
    pnpm i --save-dev @plumeria/eslint-plugin
    ```
  </Tab>
</Tabs>

## Usage [#usage]

```js
import plumeria from '@plumeria/eslint-plugin';

export default [plumeria.configs.recommended];
```

`no-invalid-selector`, `validate-pseudos`, and `validate-at-rules` read TypeScript's type information to resolve selectors that are not written as string literals — a key that comes from a variable or a `const` object, for example. Without it the rules see nothing to check and skip those keys silently.

Turn it on in the root `eslint.config.ts` by giving the TypeScript files a project service:

```ts title="eslint.config.ts"
import tseslint from 'typescript-eslint';
import { defineConfig } from 'eslint/config';
import plumeria from '@plumeria/eslint-plugin';

export default defineConfig(
  tseslint.configs.recommended,
  plumeria.configs.recommended,
  {
    files: ['**/*.{ts,tsx}'],
    languageOptions: {
      parserOptions: { projectService: true },
    },
  },
);
```

Literal selectors are still checked without this, so the rules work either way — the project service only widens what they can see.

## Rules [#rules]

`Rules: recommended`

* `'@plumeria/props-require-import': 'error'`
* `'@plumeria/no-combinator': 'error'`
* `'@plumeria/no-destructure': 'error'`
* `'@plumeria/no-inline-object': 'error'`
* `'@plumeria/no-inner-call': 'error'`
* `'@plumeria/no-invalid-selector': 'error'`
* `'@plumeria/no-mixed-styling-props': 'error'`
* `'@plumeria/no-order-dependent-overlap': 'warn'`
* `'@plumeria/no-unknown-css-properties': 'error'`
* `'@plumeria/no-unused-keys': 'warn'`
* `'@plumeria/sort-properties': 'warn'`
* `'@plumeria/format-properties': 'warn'`
* `'@plumeria/validate-values': 'warn'`
* `'@plumeria/validate-pseudos': 'error'`
* `'@plumeria/validate-at-rules': 'error'`

When using `recommended`, all rules are turned on.

Three more rules ship with the plugin and stay off until you ask for them. They
do not report a defect; they remove the room for one. See
[Optional rules](/docs/api-reference/plugins/eslint-plugin/optional-rules).

## Configuring the styling prop [#configuring-the-styling-prop]

`props-require-import`, `no-inline-object` and `no-mixed-styling-props` need to know which JSX prop carries styles. It is `classStyle` unless you changed it, so most projects configure nothing.

If you did rename it — via `styleProp` on `withPlumeria` or on the unplugin options — tell the plugin the same name. ESLint cannot read it from your bundler config, so set it once in `settings` and every rule picks it up:

```js
import plumeria from '@plumeria/eslint-plugin';

export default [
  plumeria.configs.recommended,
  {
    settings: {
      plumeria: { styleProp: 'sx' },
    },
  },
];
```

A single rule can override that if you need it to:

```js
{
  rules: {
    '@plumeria/no-mixed-styling-props': ['error', { styleProp: 'sx' }],
  },
}
```

The name must match whatever the loader or unplugin was given. If they disagree, the lint rules report against a prop the compiler never transforms.

<Cards>
  <Card title="See more about Editor integration" href="/docs/getting-started/editor-integration" />
</Cards>
