メインコンテンツまでスキップ

環境構築: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 月時点の最新)。

ツール / ライブラリバージョン役割
React19 系UI ライブラリ
Vite8 系ビルド・開発サーバー
TypeScript6 系型システム
Tailwind CSS4 系スタイリング
class-variance-authority0.7 系バリアント管理
clsx2 系条件付きクラス結合
tailwind-merge3 系Tailwind クラスの競合解決
radix-ui1 系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-mergeTailwind クラスの競合を解決cn の章
radix-uiasChild を実現する 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 関数は「複数のクラス名を安全に結合する関数」です。中で clsxtailwind-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.jsoncompilerOptions を追記します。

{
"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 変数(デザイントークン)で管理する設定(デザイントークンの章で扱います)

initsrc/index.css にデザイントークンを書き込み、src/lib/utils.tscn 関数も自動生成してくれます。つまり、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.jsontsconfig.app.json の両方に設定した
  • 実務では npx shadcn@latest init で同じ環境を自動構築できる

トラブルシューティング

Tailwind のクラスが効かない

src/main.tsx で CSS が読み込まれているか確認してください。

// src/main.tsx
import "./index.css" // この行があるか確認

パスエイリアス(@/)が認識されない

次の 3 つすべてを確認してください。

  1. vite.config.tsresolve.alias
  2. tsconfig.jsontsconfig.app.jsonpaths両方必要。TS 6 では baseUrl は書かない)
  3. @types/node がインストールされているか

モジュールが見つからないエラー

rm -rf node_modules package-lock.json
npm install

型エラーの詳細を確認したい

npx tsc --noEmit
備考

解決しない場合は公式ドキュメントを参照してください。

次章では、これから作る Button コンポーネントの「完成形」を先に見て、全体像をつかみます。