環境構築:React + Tailwind CSS 開発環境のセットアップ
この章で学ぶこと
本書の学習に必要な開発環境を、2026 年時点の最新スタックで構築します。ここで入れるツールは、すべて「デザインシステムに沿った再利用可能なコンポーネント」を作るための土台になります。
- Vite:高速なビルドツール兼開発サーバー
- React 19:UI ライブラリ
- TypeScript:型安全な JavaScript
- Tailwind CSS v4:ユーティリティファースト CSS フレームワーク
- class-variance-authority(cva):バリアント(種類)を宣言的に管理
- clsx + tailwind-merge:クラス名を安全に結合する
- radix-ui:アクセシブルな UI プリミティブ(Slot など)
それぞれが何をするのかは、これ以降の章で 1 つずつ掘り下げます。この章では「動く環境を作る」ことに集中します。
完成する開発環境
本書で使う主要なバージョンは次のとおりです(2026 年 6 月時点の最新)。
| ツール / ライブラリ | バージョン | 役割 |
|---|---|---|
| React | 19 系 | UI ライブラリ |
| Vite | 8 系 | ビルド・開発サーバー |
| TypeScript | 6 系 | 型システム |
| Tailwind CSS | 4 系 | スタイリング |
| class-variance-authority | 0.7 系 | バリアント管理 |
| clsx | 2 系 | 条件付きクラス結合 |
| tailwind-merge | 3 系 | Tailwind クラスの競合解決 |
| radix-ui | 1 系 | UI プリミティブ(Slot 等) |
バージョンは時間とともに上がります。本書のコードはこれらのメジャーバージョンを前提にしています。実際にインストールされた版は package.json で確認できます。
前提条件
Node.js が必要です。Vite 8 の動作要件を満たすため、Node.js 22.12 以上(24 LTS 推奨) を用意してください。
# Node.js のバージョン確認(22.12 以上、24 LTS 推奨)
node -v
# npm のバージョン確認
npm -v
Node.js が入っていない、またはバージョンが古い場合は、公式サイトから LTS 版をインストールしてください。
Step 1: プロジェクトの作成
Vite を使って React + TypeScript プロジェクトを作成します。
# プロジェクトを作成(react-ts テンプレート)
npm create vite@latest button-design-guide -- --template react-ts
# プロジェクトディレクトリに移動
cd button-design-guide
# 依存関係をインストール
npm install
作成直後のディレクトリ構造はおおよそ次のようになります。
button-design-guide/
├─ src/
│ ├─ App.tsx
│ ├─ main.tsx
│ └─ index.css
├─ package.json
├─ tsconfig.json # 参照のまとめ役
├─ tsconfig.app.json # アプリ用の型設定
├─ tsconfig.node.json # vite.config 用の型設定
└─ vite.config.ts
最近の Vite テンプレートでは、TypeScript の設定が tsconfig.json / tsconfig.app.json / tsconfig.node.json の 3 つに分かれています。あとでパスエイリアスを設定するときに、この分割が関係してきます。
Step 2: Tailwind CSS v4 のセットアップ
Tailwind CSS v4 では、専用の Vite プラグインを使うのが標準的な方法です。設定ファイル(tailwind.config.js)を書かずに、CSS の中で完結できます。
npm install tailwindcss @tailwindcss/vite
vite.config.ts にプラグインを追加します。
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"
import tailwindcss from "@tailwindcss/vite"
export default defineConfig({
plugins: [react(), tailwindcss()],
})
src/index.css の中身を、次の 1 行に置き換えます。
@import "tailwindcss";
これだけで Tailwind が使えるようになります。
なぜ v4 では設定ファイルが要らないのか?
v3 までは tailwind.config.js にどのファイルを対象にするか(content)などを書く必要がありました。v4 では CSS の @import "tailwindcss" を起点に自動でスキャンし、テーマも CSS の中(@theme)で定義する「CSS ファースト」な設計に変わりました。デザイントークンを CSS 変数で一元管理しやすくなり、デザインシステムと相性が良くなっています(デザイントークンの章で詳しく扱います)。
Tailwind v3 を使いたい場合は、この章の末尾の付録を参照してください。
Step 3: 必要なライブラリのインストール
Button コンポーネントの実装に必要なライブラリをインストールします。
npm install class-variance-authority clsx tailwind-merge radix-ui
それぞれの役割は次のとおりです。
| ライブラリ | 役割 | 詳しく学ぶ章 |
|---|---|---|
class-variance-authority | バリアント(variant・size)を宣言的に管理 | cva の章 |
clsx | 条件付きでクラス名を結合 | cn の章 |
tailwind-merge | Tailwind クラスの競合を解決 | cn の章 |
radix-ui | asChild を実現する Slot などの UI プリミティブ | Slot の章 |
radix-ui は、以前は @radix-ui/react-slot のように機能ごとに分かれたパッケージでした。2026 年に統合パッケージ radix-ui にまとまり、最新の shadcn/ui もこちらを使います。本書も統合版に合わせます。
Step 4: cn 関数の作成
cn という、本書全体で使う重要なユーティリティ関数を作ります。
mkdir -p src/lib
src/lib/utils.ts を作成します。
import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
cn 関数は「複数のクラス名を安全に結合する関数」です。中で clsx と tailwind-merge が何をしているのか、なぜこの 2 つを組み合わせるのかは、cn の章でじっくり解説します。今は「あとで必ず使う便利関数を用意した」とだけ理解しておけば十分です。
Step 5: パスエイリアスの設定
@/lib/utils のように、@/ で src/ ディレクトリを参照できるようにします。これにより、ファイルが深い階層にあっても import が読みやすくなります。
① vite.config.ts
Vite 側にエイリアスを教えます。
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"
import tailwindcss from "@tailwindcss/vite"
import path from "path"
export default defineConfig({
plugins: [react(), tailwindcss()],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
})
② tsconfig.json
TypeScript 側にもエイリアスを教えます。分割された設定ファイルのうち、まとめ役の tsconfig.json に compilerOptions を追記します。
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
],
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
}
}
TypeScript 6.0 から baseUrl は非推奨のハードエラー(TS5101)になりました。そのため paths の値を ./ 始まりの相対パスで書き、baseUrl は設定しません。
③ tsconfig.app.json
アプリ用の tsconfig.app.json にも同じ設定を追記します(エディタの補完や型チェックを効かせるため、両方に必要です)。
{
"compilerOptions": {
// ...既存の設定はそのまま...
"paths": {
"@/*": ["./src/*"]
}
}
}
④ @types/node のインストール
vite.config.ts で使った path の型定義を入れます。
npm install -D @types/node
Step 6: 動作確認
開発サーバーを起動して、環境が正しく動くか確認します。
npm run dev
src/App.tsx を次のように書き換えて、Tailwind が効いているか確認します。
function App() {
return (
<div className="flex min-h-screen items-center justify-center bg-gray-100">
<div className="rounded-lg bg-white p-8 shadow-lg">
<h1 className="text-2xl font-bold text-gray-800">環境構築完了!</h1>
<p className="mt-2 text-gray-600">Tailwind CSS が正しく動作しています。</p>
<button className="mt-4 rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600">
テストボタン
</button>
</div>
</div>
)
}
export default App
ターミナルに表示された URL(多くの場合 http://localhost:5173)をブラウザで開き、スタイルが当たっていれば成功です。
ポート番号は環境や設定で変わることがあります。5173 が使われていなければ、ターミナルの出力に表示された URL を確認してください。
(近道)shadcn/ui の CLI を使う場合
ここまでは「中の仕組みを理解する」ために手で環境を整えました。実務では、shadcn/ui の CLI を使うと、これらをまとめて自動化できます。
# プロジェクトを shadcn/ui 用に初期化
npx shadcn@latest init
# Button コンポーネントを追加
npx shadcn@latest add button
init を実行すると、設定ファイル components.json が作られます。
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/index.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
style: "new-york":コンポーネントのデザインの系統tailwind.config: "":Tailwind v4 では設定ファイルが不要なため空cssVariables: true:色などを CSS 変数(デザイントークン)で管理する設定(デザイントークンの章で扱います)
init は src/index.css にデザイントークンを書き込み、src/lib/utils.ts の cn 関数も自動生成してくれます。つまり、Step 2〜4 でやったことを CLI が代わりにやってくれるわけです。
本書では「なぜそうなるのか」を理解するために手で組み立てますが、新しいプロジェクトを素早く立ち上げたいときは CLI が便利です。仕組みを理解した上で CLI を使えば、生成されたコードの意味がすべて分かります。
付録: Tailwind CSS v3 を使う場合
既存プロジェクトなどで v3 を使う場合の手順です。v4 が使えるなら、この付録は読み飛ばして構いません。
npm install -D tailwindcss@3 postcss autoprefixer
npx tailwindcss init -p
生成された tailwind.config.js を編集します。
/** @type {import('tailwindcss').Config} */
export default {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: { extend: {} },
plugins: [],
}
src/index.css を次のように書きます。
@tailwind base;
@tailwind components;
@tailwind utilities;
この場合、vite.config.ts への @tailwindcss/vite プラグインの追加は不要です。本書の cn 関数やコンポーネントのコードは、v3 / v4 どちらでも同じように動作します。ただし tailwind-merge は Tailwind のバージョンに合わせる必要があります(v3 なら npm install tailwind-merge@2。詳細はcn の章の対応表を参照)。
プロジェクト構造
セットアップ完了後の構造はおおよそ次のようになります。
button-design-guide/
├─ src/
│ ├─ lib/
│ │ └─ utils.ts # cn 関数
│ ├─ components/
│ │ └─ ui/ # UI コンポーネント(これから作成)
│ │ └─ button.tsx
│ ├─ App.tsx
│ ├─ main.tsx
│ └─ index.css # @import "tailwindcss"
├─ components.json # CLI を使った場合のみ
├─ package.json
├─ tsconfig.json
├─ tsconfig.app.json
└─ vite.config.ts
この章のまとめ
- Vite + React 19 + TypeScript でプロジェクトを作成した
- Tailwind CSS v4 を Vite プラグイン +
@import "tailwindcss"でセットアップした(設定ファイル不要) cva/clsx/tailwind-merge/radix-uiを導入したcn関数を作成した(詳細はcn の章)- パスエイリアス
@/をtsconfig.jsonとtsconfig.app.jsonの両方に設定した - 実務では
npx shadcn@latest initで同じ環境を自動構築できる
トラブルシューティング
Tailwind のクラスが効かない
src/main.tsx で CSS が読み込まれているか確認してください。
// src/main.tsx
import "./index.css" // この行があるか確認
パスエイリアス(@/)が認識されない
次の 3 つすべてを確認してください。
vite.config.tsのresolve.aliastsconfig.jsonとtsconfig.app.jsonのpaths(両方必要。TS 6 ではbaseUrlは書かない)@types/nodeがインストールされているか
モジュールが見つからないエラー
rm -rf node_modules package-lock.json
npm install
型エラーの詳細を確認したい
npx tsc --noEmit
解決しない場合は公式ドキュメントを参照してください。
次章では、これから作る Button コンポーネントの「完成形」を先に見て、全体像をつかみます。