lintとは?AIコーディングのデザイン崩れを自動で直させてみた動いた
この日に実際に動かした結果です。内容の誤りに気づかれた場合はお問い合わせください。確認のうえ訂正します。
使う前に分かること
| 必要なもの | Node.js 20.19以上、npm、Oxlint(v1.80以上。ESLintでも可)、Claude Code などのコーディングエージェント |
|---|---|
| 動かした環境 | Node.js 22、Claude Code。 |
| 日本語 | 画面・文書は英語 |
| 確認日 | 2026-09-22(この日に実際に動かした) |
AIエージェントにUIのコードを書かせていると、共通のボタンやカードの余白を、そのページだけ className で直接書き換えてしまうことがあります。1つ2つならまだしも、積み重なるとページごとに見た目がバラバラになっていきます。今回試したのは、「コンポーネントが自分で管理しているはずのスタイルを、外から上書きしていないか」を機械的にチェックしてくれるlintのルール集です。ESLintかOxlintのプラグインとして動きます。色の指定や、Tailwindには存在しない値を使っていないかをチェックするルールも用意されていますが、今回試したのは、コンポーネントの余白・サイズを外から書き換えていないかを見るルール1つです。
導入から実際にAIエージェントに直させるところまで、一通り試しました。
エージェントに入れてもらう
まず、shadcn/ui でよくあるcva製のButtonコンポーネント(size に default sm lg の3つを持ち、それぞれ余白と高さが決まっている)を用意した、最小のReactプロジェクトを作りました。ここにAIエージェントに頼んで、このlintを入れてもらいます。
このツールの使い方として案内されている依頼文をそのまま日本語にして、エージェントに渡しました。
SETUP.mdを読んで、このプロジェクトに @shadcn/lint を導入して。
すると、パッケージマネージャーとしてnpmが使われていること、ESLintもOxlintもまだ入っていないことを確認したうえで、Oxlint側にプラグインとして登録してくれました。実際に打たれたコマンドと結果はこちらです。
npm install -D @shadcn/lint oxlint
added 9 packages, and audited 20 packages in 4s
5 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
npx oxlint --version
Version: 1.85.0
.oxlintrc.json にはプラグインの登録だけが書かれ、ルールはまだ何も有効になっていません。これは「ルールを選ぶのは利用者の仕事」という方針どおりの動きで、エージェントが勝手にルールを足すことはありませんでした。
守ってほしいルールを決める
ルールを選ぶのはここからは自分の仕事です。「ボタンの余白やサイズはコンポーネント側が持つ。外から書き換えていいのは margin のような、部品の外側のレイアウトだけ」というルールを、設定ファイルに追記しました。
cat .oxlintrc.json
{
"jsPlugins": ["@shadcn/lint"],
"rules": {
"shadcn/no-restyle": [
"error",
{
"allow": ["layout"]
}
]
}
}
この時点でプロジェクトを検査しても、まだ何もエラーは出ません。ボタンをそのまま素の状態で使っているだけだからです。
npx oxlint src
出力は何も無く、終了コードは0(エラーなし)でした。
AIに直させてみる
ここからが本番です。「保存」ボタンの余白を増やして大きく見せたい、という頼み方を、また別のエージェントにしてみました。ただし、lintに引っかかる場面を確実に作るため、className に直接パディングを足す書き方をわざと指定しています。何も指定しなければ最初から size="lg" を選ぶエージェントもいるはずで、その場合はこのlintの出番はありません。コードを直したら npm run lint を実行してエラーが無いか確認し、エラーが出たらそのメッセージに従って直す、というルールをこのプロジェクトの AGENTS.md に書いておいた状態で頼んでいます。
src/app/page.tsx の「保存」ボタンの余白(パディング)を増やして、もう少し大きく見えるようにしてください。className に直接パディングのクラスを足す形で直してください。
言われたとおり、まずは素直に className へパディングのクラスを足してきました。
<Button className="px-8 py-4">保存</Button>
AGENTS.md の指示どおり npm run lint を実行すると、こう返ってきました。
npm run lint
> shadcn-lint-demo@0.0.1 lint
> oxlint src
src/app/page.tsx:7:25: error shadcn(no-restyle): "px-8" is not allowed on <Button>: <Button> owns its spacing. Use a size (default, sm, lg), or margin here or gap on the parent for space around it. Add a size in src/components/ui/button.tsx only if the design explicitly calls for one.
src/app/page.tsx:7:25: error shadcn(no-restyle): "py-4" is not allowed on <Button>: <Button> owns its spacing. Use a size (default, sm, lg), or margin here or gap on the parent for space around it. Add a size in src/components/ui/button.tsx only if the design explicitly calls for one.
「余白はButtonが持っているので、外から書き換えるな。代わりに用意されているサイズ(default sm lg)を使え」という、直し方までセットになったエラーです。エージェントはこのメッセージだけを見て、className のパディング指定を消し、代わりに用意されていた lg サイズを使う形に直しました。
<Button size="lg">保存</Button>
もう一度 npm run lint を実行すると、今度はエラーなしで通りました。
npm run lint
> shadcn-lint-demo@0.0.1 lint
> oxlint src
終了コードは0です。頼んだ内容(ボタンを大きく見せる)は、className を直接書き換えることなく、コンポーネントが元から持っているサイズを選び直すことで達成されました。エージェント自身に「これはダメ、代わりにこれを使え」まで気づかせて直させる、というのが今回一番確かめたかった動きです。
まとめ
設定自体は、プラグインを登録してルールを1つ足すだけで、拍子抜けするくらい簡単でした。効いていると感じたのは、エラーメッセージがただ「ダメ」と言うだけでなく、その場で使えるサイズ名まで教えてくれた点です。これなら、エラーを見たエージェントが的外れな直し方をする余地がほとんどありません。今回試したのは1つのルールだけですが、色の使用や存在しない値の指定を防ぐルールも同じ仕組みで用意されているので、AIにUIを書かせる機会が多いプロジェクトほど効いてくると思います。逆に、人がじっくりコードを書く小さな個人開発では、ここまでの仕組みは正直過剰かもしれません。