Skip to content

Setup

Todo lo necesario para tener oxlint-tailwindcss corriendo en un proyecto, en una sola página. Elige la sección que coincida con la forma de tu repo — proyecto simple o monorepo — y copia el snippet.

1. Instalación

bash
pnpm add -D oxlint oxlint-tailwindcss

Requisitos:

  • oxlint 1.43.0 o posterior.
  • Tailwind CSS v4. El plugin carga tu design system vía @tailwindcss/node y solo entiende sintaxis v4 (@import "tailwindcss";, @theme { ... }).
  • Node.js 20 o posterior para el proceso del linter.

2. Configuración mínima

Crea o extiende tu .oxlintrc.json en la raíz del proyecto:

jsonc
{
  "$schema": "./node_modules/oxlint/configuration_schema.json",
  "jsPlugins": ["oxlint-tailwindcss"],
  "rules": {
    "tailwindcss/no-unknown-classes": "error",
    "tailwindcss/no-conflicting-classes": "error",
    "tailwindcss/no-duplicate-classes": "warn",
    "tailwindcss/enforce-sort-order": "warn",
    "tailwindcss/enforce-canonical": "warn"
  },
  "settings": {
    "tailwindcss": {
      "entryPoint": "src/styles.css"
    }
  }
}

settings.tailwindcss.entryPoint es obligatorio en v1.0.0 y debe apuntar al archivo CSS donde haces @import "tailwindcss"; y (opcionalmente) declaras tus tokens @theme { ... }. El plugin lee ese archivo para construir el design system que todas las reglas consultan.

Eso es todo. Ejecuta oxlint y el plugin va a lintear cada archivo JS / TS / JSX / TSX / Vue / Svelte del proyecto contra el design system cargado desde src/styles.css.

3. Conjunto de reglas recomendado

Si quieres un set "bendecido" que detecte problemas reales sin ser ruidoso, activa estas:

jsonc
{
  "$schema": "./node_modules/oxlint/configuration_schema.json",
  "jsPlugins": ["oxlint-tailwindcss"],
  "rules": {
    // Correctness — atrapan bugs reales
    "tailwindcss/no-conflicting-classes": "error",
    "tailwindcss/no-deprecated-classes": "error",
    "tailwindcss/no-duplicate-classes": "warn",
    "tailwindcss/no-unknown-classes": "error",

    // Modernización — mantiene las clases en su forma canónica actual
    "tailwindcss/enforce-canonical": "warn",
    "tailwindcss/no-unnecessary-arbitrary-value": "warn",

    // Estilo y consistencia
    "tailwindcss/enforce-sort-order": "warn",
    "tailwindcss/consistent-variant-order": "warn",
    "tailwindcss/enforce-consistent-important-position": "warn",
    "tailwindcss/no-unnecessary-whitespace": "warn"
  },
  "settings": {
    "tailwindcss": {
      "entryPoint": "src/styles.css"
    }
  }
}

Agrega reglas extra a medida que las necesites:

  • enforce-logical / enforce-physical si tienes una preferencia de dirección.
  • no-arbitrary-value, no-hardcoded-colors, no-restricted-classes si quieres enforcement de design-system.
  • prefer-theme-tokens para preferir utilidades nombradas sobre referencias var().

El catálogo completo está en Reglas. Cada página documenta el comportamiento exacto, las opciones disponibles, y ejemplos ✓ / ✗.

4. Verifica el setup

La prueba más rápida es escribir mal una clase a propósito:

tsx
<div className="flx items-cetner" />

oxlint debería marcar ambas clases con no-unknown-classes, y las sugerencias flex / items-center aparecer en tu editor.

Si en cambio ves un diagnóstico designSystemUnavailable, significa que entryPoint no está configurado o apunta a un archivo que el plugin no puede leer. El mensaje del diagnóstico te dice exactamente qué ruta intentó — copia esa en tu setting entryPoint. Un entryPoint relativo se resuelve respecto al directorio del .oxlintrc.json más cercano que lo contiene (el config que lo declara), cayendo de vuelta al directorio donde corres oxlint.

5. Setups de monorepo

Si tienes un solo .oxlintrc.json en la raíz y varios archivos CSS de Tailwind entre los packages, usa la forma de mapping — gana el primer glob que coincide:

jsonc
{
  "settings": {
    "tailwindcss": {
      "entryPoint": [
        { "files": "packages/ui/**",    "use": "packages/ui/src/styles.css" },
        { "files": "packages/admin/**", "use": "packages/admin/src/admin.css" },
        { "files": "packages/web/**",   "use": "packages/web/src/app.css" },
        { "files": "**",                "use": "src/global.css" }
      ]
    }
  }
}

Agrega un fallback "**" al final para que cualquier archivo fuera de los globs explícitos resuelva a uno por defecto.

Si en cambio cada package tiene su propio .oxlintrc.json extendiendo una base compartida, simplemente pon entryPoint: "./src/styles.css" (string) en los settings de cada package. Mira la guía de monorepo para ambos patrones lado a lado.

6. Coexistencia con oxfmt o prettier-plugin-tailwindcss

enforce-sort-order coincide byte por byte con oxfmt y prettier-plugin-tailwindcss si las tres herramientas leen el mismo CSS. Por defecto, oxfmt y el plugin de prettier usan el tailwindcss/theme.css bundled — que no conoce tus tokens @theme personalizados. Apúntalos a tu CSS:

jsonc
// .oxfmtrc.json
{ "sortTailwindcss": { "stylesheet": "./src/styles.css" } }

// .prettierrc
{
  "plugins": ["prettier-plugin-tailwindcss"],
  "tailwindStylesheet": "./src/styles.css"
}

Lee la guía completa de interop para el porqué y los edge cases con tagged templates y plugins como @tailwindcss/typography.

7. Yendo más allá

  • Ajustar extractors: por defecto el plugin escanea className / class, ~14 callees (cn, clsx, cva, twMerge, …), templates con tw, y variables que matchean /^classNames?$/, /^classes$/, /^styles?$/. Agrega attributes, callees, tags, variablePatterns, o quita defaults vía exclude. Mira la referencia de settings.
  • Ajustar timeouts: settings.tailwindcss.timeout (ms, default 60000) limita cuánto espera el plugin al worker (hilo) que precomputa el design system. CI lento puede necesitar subirlo.
  • Logging de debug: settings.tailwindcss.debug: true (o DEBUG=oxlint-tailwindcss) loguea qué CSS entry point resolvió por cada archivo lintado.
  • ¿Vienes de v0.x? Lee la guía de migraciónentryPoint ahora es obligatorio y la forma legacy string[] fue removida.

Released under the MIT License.