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:


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

ConfigDescriptionIncluded Rules
recommendedNord + Tailwind rules (warnings)@nordhealth/logical-selectors, @nordhealth/no-unknown-legacy-classes, better-tailwindcss rules
recommended-errorSame as above but as errors@nordhealth/logical-selectors, @nordhealth/no-unknown-legacy-classes, better-tailwindcss rules
nordNord rules only (warnings)@nordhealth/logical-selectors, @nordhealth/no-unknown-legacy-classes
nord-errorNord rules only (errors)@nordhealth/logical-selectors, @nordhealth/no-unknown-legacy-classes
vueRecommended + Vue parser@nordhealth/logical-selectors, @nordhealth/no-unknown-legacy-classes, better-tailwindcss rules, Vue parser
vue-errorVue config with errors@nordhealth/logical-selectors, @nordhealth/no-unknown-legacy-classes, better-tailwindcss rules, Vue parser

Nord Rules

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:p-is-m n:m-ie-l n:border-is">

Converts physical directions to logical equivalents:

PhysicalLogicalDescription
pl/prp-is/p-iePadding inline-start/end
ml/mrm-is/m-ieMargin inline-start/end
pt/pbp-bs/p-bePadding block-start/end
mt/mbm-bs/m-beMargin block-start/end
left/rightinset-is/inset-iePosition inline-start/end
top/bottominset-bs/inset-bePosition block-start/end
border-l/border-rborder-is/border-ieBorder inline-start/end
rounded-tlrounded-ssBorder radius start-start
rounded-trrounded-seBorder radius start-end
rounded-blrounded-esBorder radius end-start
rounded-brrounded-eeBorder radius end-end

Migrates deprecated Nord CSS classes (n-*) to their Tailwind equivalents (n:*). Auto-fixable.

This rule is off by default. Enable it during migration, then disable when complete. See the Migration Guide for details.

<!-- 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:

CategoryDescription
spacingMargin, padding, gap classes
bordersBorder width, color, radius classes
typographyFont size, weight, family, line-height
colorsText, background, status colors
layoutFlex, grid, alignment, container
componentsForm elements, icons
utilitiesShadows, 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"]
}]

Flags n-* classes that aren't part of the Nord CSS Framework. This rule helps you:

This rule is useful for all legacy CSS users to ensure you're only using valid Nord classes. It works regardless of whether you're planning to migrate to Tailwind.

<!-- 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:

For the full list of rules and configuration options, see the eslint-plugin-better-tailwindcss documentation.

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:

FrameworkAttributes detected
HTML/Reactclass, className
Vueclass, :class, v-bind:class
Svelteclass, class:directive
Angular[class], [ngClass], [class.name]
Astroclass, class:list

Supported utility functions:

FunctionLibrary
clsx, classnames, classNamesclsx / classnames
cn, cxCommon aliases
cvaclass-variance-authority
tvtailwind-variants
twMerge, twJointailwind-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" } }
})

Was this page helpful?

YesNo
Send feedback

We use this feedback to improve our documentation.

 
Edit page
Choose therapy brandChoose veterinary brandAbout Nord Design SystemGet support