design-token-lint とは?
design-token-lint が何をするか、なぜ存在するかの概要。
Tailwind CSS は数百もの数値ユーティリティ — p-1 から p-96、gap-2、mt-8 — と、bg-red-500、text-gray-300 のようなシェードを持つデフォルトカラーパレットを提供しています。これらのユーティリティは便利ですが、デザインシステムを完全に無視することを可能にします。開発者はデザイントークンを参照せず、任意のスペーシング値や色を選ぶことができてしまいます。
@takazudo/zudo-design-token-lint はこれを検出するリンターです。禁止パターンに一致する Tailwind クラス名をソースファイルからスキャンし、違反として報告します — セマンティックな代替案へと開発者を導きます。
問題点
p-4 を使ったコンポーネントと p-6 を使ったコンポーネントは見た目が似ていても、共有されたセマンティックな意味を持ちません。これが大きなプロジェクト全体に広がると、場当たり的なスペーシング値が無数に生まれ、デザイントークンではなく Tailwind のパレットから色が選ばれ、一貫性を強制するツールも存在しない状態になります。
デザインシステムは spacing-md、color-surface、text-primary のようなセマンティックなトークンを定義することで、それらの値に契約を与えます。生のユーティリティはその契約を無言で回避します。
詳しい考え方はメソドロジーのページを参照してください。
仕組み
ファイルのスキャン — リンターはソースファイル(
.tsx、.jsx、.astro、.vue、.htmlなど)を読み込み、静的なclassName/class属性、cn()、clsx()などの構文に対してパターンマッチングで Tailwind クラス名を抽出します。Vue の:classや Svelte のclass:nameディレクティブのような動的なバインディング構文は評価しません — 既知の制限事項を参照してください。ルールとの照合 — 抽出された各クラスは
.design-token-lint.jsonで定義された禁止パターンと照合されます。パターンにはプレースホルダーを使用します:{n}— 任意の Tailwind 数値ステップにマッチ(p-{n}はp-4、p-6、p-12などにマッチ){color}— 任意のデフォルト Tailwind カラー名にマッチ(bg-{color}-{shade}はbg-red-500にマッチ){shade}— 数値シェード(50〜950)にマッチ
違反の報告 — 違反はファイルパス、行番号、クラス名、そして期待されるトークンカテゴリを示す理由文字列とともに報告されます。
src/Button.tsx
L12: p-4 — Numeric spacing "p-4" — use a semantic spacing token or arbitrary value
src/Card.tsx
L7: bg-gray-200 — Default Tailwind color "bg-gray-200" — use a design system color token 主な機能
CLI ツール —
npx design-token-lintでプロジェクトをリント。CI 統合のため違反があればコード1で終了設定可能なルール —
.design-token-lint.jsonで禁止パターンと明示的な許可リストを定義パターンプレースホルダー —
{n}、{color}、{shade}により 1 つのルールでユーティリティファミリー全体をカバー無視構文 —
/で個別行を、/ design- token- lint- ignore /でファイル全体を抑制/ design- token- lint- ignore- file プログラマティック API — ビルドツールやエディタとの統合のための
lintFile()、lintContent()、checkClass()ブラウザプレイグラウンド — インストールなしでパターンとクラスをインタラクティブに試せる
技術スタック
TypeScript、Node.js 18+。CLI バイナリとインポート可能なライブラリを持つ npm パッケージとして配布。ランタイム依存関係: chalk(ターミナルカラー)と glob(ファイルスキャン)。Tailwind への依存なし — 内部ではなく文字列パターンマッチングで動作します。
インテグレーション
ソースファイルで静的な Tailwind クラス属性を使用する任意のフレームワーク(React、Astro、プレーン HTML、および静的な class="..." 属性を使う Vue/Svelte テンプレート)で動作します。Vue の :class/v-bind:class バインディングと Svelte の class:name ディレクティブは正しく抽出されません(既知の制限事項を参照)。以下と統合できます:
CI/CD — GitHub Actions や任意のパイプラインのステップとして実行
Git フック — lefthook または husky でプッシュ前に実行
ビルドツール — Vite プラグイン、webpack ローダー、またはカスタムスクリプトでプログラマティック API を使用
エディタ — プログラマティック API はエディタプラグイン作者をサポート