@dayflower/tw-lint

中文文档
0.5.3发布于 2026/10/25MITTypeScriptES Module构建来源已验证近 30 天下载 2246

An unofficial Tailwind CSS linter CLI powered by the Tailwind CSS language server.

原始使用文档
文档目录13 节
  1. Features
  2. Requirements
  3. Installation
  4. Usage
  5. Options
  6. Configuration file
  7. Exit codes
  8. GitHub Action
  9. Inputs
  10. Outputs
  11. Programmatic API
  12. How it works
  13. License

tw-lint

npm version

An unofficial command-line linter for Tailwind CSS powered by the Tailwind CSS language tooling.

[!NOTE] This is an unofficial project. It is not affiliated with, endorsed by, or sponsored by Tailwind Labs. "Tailwind CSS" is a trademark of Tailwind Labs Inc.

Features

  • Detects the problems surfaced by Tailwind CSS IntelliSense, including: cssConflict, invalidApply, invalidScreen, invalidVariant, invalidConfigPath, invalidTailwindDirective, invalidSourceDirective, recommendedVariantOrder, usedBlocklistedClass, deprecatedAtRule, suggestCanonicalClasses.
  • Adjust each rule's severity (ignore / warning / error) via --severity <rule=level> or a config file.
  • Works with both Tailwind CSS v3 (tailwind.config.js) and v4 (CSS-based config) projects — the version is auto-detected by the language server.
  • Lints HTML, JSX/TSX, Vue, Svelte, Astro, PHP and other template languages, as well as CSS files.
  • Human-readable text output, machine-readable --format json, and --format github for GitHub Actions annotations.
  • --fix / --fix-dry-run apply the language server's quick-fixes.
  • CI-friendly exit codes and --max-warnings.

Requirements

  • Node.js >= 22
  • A Tailwind CSS project in the workspace:
    • v3: a tailwind.config.{js,cjs,mjs,ts} and tailwindcss installed in the project's node_modules.
    • v4: a CSS entrypoint that imports Tailwind (e.g. @import "tailwindcss";) and tailwindcss installed in the project's node_modules.

The language server loads the project's own tailwindcss (and its config) from node_modules to compute diagnostics. This means the target project's dependencies must already be installed before linting. In CI, run your install step (e.g. npm ci) first:

npm ci
npx tw-lint "src/**/*.{tsx,html}"

If the dependencies are not installed, no Tailwind project is detected and the linter reports no problems.

Installation

npm install --save-dev @dayflower/tw-lint

Usage

tw-lint [globs...] [options]

Examples:

# Lint everything (default globs) in the current project
tw-lint

# Lint specific files
tw-lint "src/**/*.{tsx,html}"

# Machine-readable output
tw-lint "src/**/*.tsx" --format json

# Treat class conflicts as errors
tw-lint --severity cssConflict=error

# Apply fixes
tw-lint "src/**/*.html" --fix

# Apply fixes in a single pass (do not loop)
tw-lint "src/**/*.html" --fix --fix-passes 1

When a single class attribute has fixes that overlap (for example a conflicting-utility removal and a canonical-class rewrite), only the non-overlapping edits can be applied in one pass. --fix therefore runs up to --fix-passes passes (default 10, like ESLint's autofix), re-applying fixes until nothing changes. Set --fix-passes 0 or --fix-passes 1 to keep the old single-pass behaviour.

Fixed problems disappear from the report once applied (only a count is shown, as with ESLint). Pass --report-fixed to also list each applied fix under a Fixed section (and, with --format json, a fixedMessages array per file):

Fixed
src/Button.tsx
  4:17  fixed  Replace with 'w-xl'  suggestCanonicalClasses
  4:27  fixed  Delete 'p-4'         cssConflict
✔ 2 issues fixed

Options

OptionDescription
--cwd <dir>Project root directory (default: current directory).
--format <text|json|github>Output format (default: text). github emits GitHub Actions annotations.
-c, --config <file>Path to a linter config file (see below).
--severity <rule=level>Override a rule severity (ignore/warning/error). Repeatable. Overrides the config file.
--tailwind-config <file>Force a specific Tailwind config file.
--max-warnings <n>Exit non-zero if warnings exceed this number.
--quietReport errors only.
--fixApply fixes and write changes to files.
--fix-dry-runCompute fixes without writing changes.
--fix-passes <n>Max fix passes when fixing (default 10; 0 or 1 = single pass).
--report-fixedList the individual fixes applied (off by default).
--no-error-on-no-projectExit 0 instead of 2 when no Tailwind project is detected.
--verbosePrint language server logs to stderr.

Configuration file

Rule severities (and a few other settings) can be persisted in a config file so they don't have to be passed on the command line every time. By default the linter looks in the project root for, in order:

  1. tw-lint.config.json
  2. .tw-lintrc.json
  3. a "tw-lint" key in package.json

Use -c, --config <file> to point at a specific file instead.

{
  // Rule severities: "ignore" | "warning" | "error"
  "rules": {
    "cssConflict": "error",
    "recommendedVariantOrder": "ignore"
  },
  // Attributes/functions whose string values are scanned for classes
  "classAttributes": ["class", "className", "tw"],
  "classFunctions": ["clsx", "cva", "cn"],
  // Map extra language ids to a known one (e.g. for custom templates)
  "includeLanguages": { "plaintext": "html" },
  // Equivalent to --tailwind-config
  "tailwindConfig": "./tailwind.config.ts",
  // Equivalent to --fix-passes (max fix passes; 0 or 1 = single pass)
  "fixPasses": 10,
  // Equivalent to --report-fixed (list the fixes applied)
  "reportFixed": false
}

These rules are the Tailwind CSS IntelliSense lint settings (tailwindCSS.lint.*). They are not part of your tailwind.config.js, which only configures Tailwind's design system.

--severity overrides the config file on a per-rule basis, and --tailwind-config overrides tailwindConfig.

Available rules

Every value is "ignore", "warning" or "error". The defaults match the Tailwind CSS IntelliSense extension.

RuleDefaultDescription
invalidScreenerrorUnknown screen name in a @screen directive.
invalidVarianterrorUnknown variant (e.g. hvr:underline).
deprecatedAtRulewarningThe legacy @variant name(...) syntax is used to define a custom variant in v4; use @custom-variant instead.
invalidTailwindDirectiveerrorUnknown value in a @tailwind directive.
invalidApplyerrorA class used in @apply cannot be applied.
invalidConfigPatherrorA theme() / config() path that does not exist.
cssConflictwarningTwo classes on the same element apply the same CSS properties (e.g. p-2 p-4).
recommendedVariantOrderwarningStacked variants are not in the recommended order.
usedBlocklistedClasswarningA class listed in the project's blocklist is used.
suggestCanonicalClasseswarningSuggests the canonical class for an equivalent one.
invalidSourceDirectiveerrorInvalid @source directive (Tailwind v4).

These are defined by the Tailwind CSS language service; the authoritative descriptions are the tailwindCSS.lint.* settings in the Tailwind CSS IntelliSense extension settings (the table above follows the same order). The rule names accepted here are the keys under tailwindCSS.lint.

Exit codes

  • 0 — no errors (and warnings within --max-warnings, if set).
  • 1 — errors found, or --max-warnings exceeded.
  • 2 — the linter itself failed, or no Tailwind project was detected for the linted files (nothing was linted). Pass --no-error-on-no-project to treat the latter as 0 instead.

GitHub Action

tw-lint ships as a reusable GitHub Action. It reports problems as inline annotations on the run and pull request. As with the CLI, install the target project's dependencies first so the language server can detect the project.

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci # install the project's own tailwindcss
      - uses: dayflower/tw-lint@v1
        with:
          globs: "src/**/*.{tsx,html}"
          max-warnings: "0"

Inputs

Each input maps to the matching CLI option:

InputCLI optionDefault
globspositional globs(none)
working-directory--cwd.
config--config(none)
severity--severity (one per line)(none)
tailwind-config--tailwind-config(none)
max-warnings--max-warnings(none)
quiet--quietfalse
fix--fixfalse
fix-dry-run--fix-dry-runfalse
fix-passes--fix-passes10
report-fixed--report-fixedfalse
error-on-no-project--no-error-on-no-project (inverted)true
verbose--verbosefalse

Outputs

error-count, warning-count, and fix-count.

The github output format is also available from the CLI directly via tw-lint --format github if you prefer to run the binary yourself in a workflow.

Programmatic API

import { runLint, createTailwindSettings } from '@dayflower/tw-lint'

const summary = await runLint({
  cwd: process.cwd(),
  patterns: ['src/**/*.tsx'],
  settings: createTailwindSettings({ rules: { cssConflict: 'error' } }),
})

console.log(summary.errorCount, summary.warningCount)

How it works

Instead of re-implementing lint rules, this tool drives @tailwindcss/language-server as a headless LSP client. The server performs project detection (Tailwind v3 and v4), config loading and validation using @tailwindcss/language-service internally — the very same engine behind the Tailwind CSS IntelliSense editor extension. This tool collects the resulting diagnostics, reports them on the command line, and can apply the server's quick-fixes.

  1. Spawns tailwindcss-language-server --stdio and connects over JSON-RPC.
  2. Initializes the workspace and responds to the server's workspace/configuration requests with the lint settings.
  3. Opens each matched document to trigger project initialization, waits for the project to initialize, then forces a fresh validation per document and collects the published diagnostics.
  4. For --fix, requests textDocument/codeAction quick-fixes and applies the returned edits.

License

MIT

版本与发布记录

@dayflower/tw-lint 共发布 9 个版本,首次发布于 2026/07/01;过去 12 个月发布了 9 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.5.3latest2026/10/2519 天前
0.5.22026/09/181 个月前
0.5.12026/08/063 个月前
0.5.02026/08/033 个月前
0.4.02026/07/034 个月前
0.3.02026/07/024 个月前

关于 @dayflower/tw-lint 的常见问题

@dayflower/tw-lint 是什么?

An unofficial Tailwind CSS linter CLI powered by the Tailwind CSS language server.

如何安装 @dayflower/tw-lint?

在项目目录运行 npm install @dayflower/tw-lint,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 tw-lint,可以用 npx tw-lint 直接运行。

@dayflower/tw-lint 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@dayflower/tw-lint 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@dayflower/tw-lint 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@dayflower/tw-lint 可以商用吗?

@dayflower/tw-lint 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@dayflower/tw-lint 的下载量有多少?

根据 npm 官方下载统计,@dayflower/tw-lint 在 2026/10/12 – 2026/11/10 这 30 天内被下载 2,246 次,日均约 75 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@dayflower/tw-lint 还在维护吗?

最新版本 0.5.3 发布于 2026/10/25(19 天前);至今共发布 9 个版本,其中过去 12 个月发布了 9 个;首次发布于 2026/07/01。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。