Clickto expand
ESLint Plugin
ESLint plugin for Nord Design System - enforces logical CSS selectors, assists with migration from legacy classes, and integrates Tailwind best practices.
The @nordhealth/eslint-plugin helps you:
- Enforce logical CSS properties for better RTL/LTR support
- Migrate from legacy CSS with auto-fixable rules
- Follow Tailwind best practices with integrated rules from better-tailwindcss
Installation
npm install @nordhealth/eslint-plugin --save-dev
Usage
The plugin provides several preset configurations. Add one to your eslint.config.js:
import nordPlugin from '@nordhealth/eslint-plugin'
export default [
// Recommended: Nord rules + Tailwind best practices
nordPlugin.configs.recommended,
// For Vue projects (includes Vue parser)
nordPlugin.configs.vue,
]
Available Configs
| Config | Description | Included Rules |
|---|---|---|
recommended | Nord + Tailwind rules (warnings) | @nordhealth/logical-selectors, @nordhealth/no-unknown-legacy-classes, better-tailwindcss rules |
recommended-error | Same as above but as errors | @nordhealth/logical-selectors, @nordhealth/no-unknown-legacy-classes, better-tailwindcss rules |
nord | Nord rules only (warnings) | @nordhealth/logical-selectors, @nordhealth/no-unknown-legacy-classes |
nord-error | Nord rules only (errors) | @nordhealth/logical-selectors, @nordhealth/no-unknown-legacy-classes |
vue | Recommended + Vue parser | @nordhealth/logical-selectors, @nordhealth/no-unknown-legacy-classes, better-tailwindcss rules, Vue parser |
vue-error | Vue config with errors | @nordhealth/logical-selectors, @nordhealth/no-unknown-legacy-classes, better-tailwindcss rules, Vue parser |
migrate-spacing | Opt-in numeric spacing migration (warnings); add after other presets | Spacing-only legacy migration and restricted-class replacements |
Numeric spacing migration
Add nordPlugin.configs['migrate-spacing'] after your usual presets to migrate n:p-s to n:p-2, or n-padding-s to n:p-2 through successive fix passes. Numeric and px utilities are left unchanged. Arbitrary classes referencing --n-space-* produce warnings for manual review.
The preset preserves variants and important modifiers. Named typography, border radius, icon size and component APIs are unaffected. See the numeric spacing migration guide for configuration, compatibility and Stylelint guidance.
Nord Rules
@nordhealth/logical-selectors Recommended
Enforces logical CSS properties over physical ones for better RTL/LTR support. Auto-fixable.
<!-- Bad -->
<div class="n:pl-m n:mr-l n:border-l">
<!-- Good -->
<div class="n:ps-m n:me-l n:border-s">
Converts physical directions to logical equivalents (using TW4 built-in names):
| Physical | Logical | Description |
|---|---|---|
pl/pr | ps/pe | Padding inline-start/end |
ml/mr | ms/me | Margin inline-start/end |
pt/pb | pbs/pbe | Padding block-start/end |
mt/mb | mbs/mbe | Margin block-start/end |
left/right | start/end | Position inline-start/end |
top/bottom | inset-bs/inset-be | Position block-start/end |
border-l/border-r | border-s/border-e | Border inline-start/end |
border-t/border-b | border-bs/border-be | Border block-start/end |
rounded-tl | rounded-ss | Border radius start-start |
rounded-tr | rounded-se | Border radius start-end |
rounded-bl | rounded-es | Border radius end-start |
rounded-br | rounded-ee | Border radius end-end |
w/h | inline/block | Inline/block size |
min-w/min-h | min-inline/min-block | Min inline/block size |
max-w/max-h | max-inline/max-block | Max inline/block size |
@nordhealth/no-legacy-classes Recommended
Migrates deprecated Nord CSS classes (n-*) to their Tailwind equivalents (n:*). Auto-fixable.
<!-- Bad -->
<div class="n-padding-m n-margin-l n-color-text-weak">
<!-- Good (auto-fixed) -->
<div class="n:p-m n:m-l n:text-weak">
Available categories:
| Category | Description |
|---|---|
spacing | Margin, padding, gap classes |
borders | Border width, color, radius classes |
typography | Font size, weight, family, line-height |
colors | Text, background, status colors |
layout | Flex, grid, alignment, container |
components | Form elements, icons |
utilities | Shadows, z-index, transitions, misc |
Configuration examples:
// Enable only specific categories
"@nordhealth/no-legacy-classes": ["warn", {
categories: ["spacing", "colors"]
}]
// Disable specific categories (enable all others)
"@nordhealth/no-legacy-classes": ["warn", {
disabledCategories: ["components"]
}]
@nordhealth/no-unknown-legacy-classes Recommended
Flags n-* classes that aren't part of the Nord CSS Framework. This rule helps you:
- Catch typos in class names (e.g.,
n-maring-minstead ofn-margin-m) - Identify deprecated classes that have been removed from the framework
- Find custom classes that may need to be migrated or replaced
<!-- These will be flagged -->
<div class="n-maring-m"> <!-- typo: should be n-margin-m -->
<div class="n-padding-medium"> <!-- invalid: should be n-padding-m -->
<div class="n-custom-class"> <!-- unknown: not a Nord class -->
<!-- These are valid Nord classes -->
<div class="n-margin-m n-padding-l n-color-text">
Disable this rule if needed:
rules: {
"@nordhealth/no-unknown-legacy-classes": "off"
}
Tailwind Rules
The plugin includes the recommended rules from eslint-plugin-better-tailwindcss:
- Consistent class ordering - Ensures classes are in a consistent order
- No duplicate classes - Prevents accidentally duplicating classes
- No conflicting classes - Catches classes that conflict with each other
- Shorthand enforcement - Suggests shorthand classes where possible
- Canonical classes - Enforces canonical Tailwind class names
Enabling no-unknown-classes
The better-tailwindcss/no-unknown-classes rule is not enabled by default because it requires project-specific configuration:
import nordPlugin from '@nordhealth/eslint-plugin'
export default [
nordPlugin.configs.recommended,
{
settings: {
'better-tailwindcss': {
entryPoint: './path/to/your/tailwind.css'
}
},
rules: {
'better-tailwindcss/no-unknown-classes': 'warn'
}
}
]
Custom Configuration
You can customize individual rules:
import nordPlugin from '@nordhealth/eslint-plugin'
export default [
nordPlugin.configs.recommended,
{
rules: {
// Enable migration rules
'@nordhealth/no-legacy-classes': ['warn', {
categories: ['spacing', 'borders', 'colors', 'utilities']
}],
// Change severity
'@nordhealth/logical-selectors': 'error',
}
}
]
Class Detection
The plugin detects classes across multiple frameworks and patterns:
Supported frameworks:
| Framework | Attributes detected |
|---|---|
| HTML/React | class, className |
| Vue | class, :class, v-bind:class |
| Svelte | class, class:directive |
| Angular | [class], [ngClass], [class.name] |
| Astro | class, class:list |
Supported utility functions:
| Function | Library |
|---|---|
clsx, classnames, classNames | clsx / classnames |
cn, cx | Common aliases |
cva | class-variance-authority |
tv | tailwind-variants |
twMerge, twJoin | tailwind-merge |
This means rules will work in code like:
// All of these are detected
<div className="n:p-m n:text-default" />
<div className={cn("n:p-m", condition && "n:text-weak")} />
<div className={clsx("n:flex", "n:gap-m")} />
const buttonVariants = cva("n:px-m n:py-s", {
variants: { size: { lg: "n:px-l n:py-m" } }
})