はじめに
「shadcn/uiは良いけど、Reactプロジェクトじゃないと使えないんだよな」
この悩み、同じように感じている人も多いんじゃないでしょうか。個人的にはshadcn/uiのデザインが好きで、でもPHPやDjango、素のHTMLプロジェクトでも同じクオリティのUIを使いたい場面って結構あるんですよ。
そこで見つけたのがBasecoat。キャッチコピーは「All of the shadcn/ui magic, none of the React」。これ、意外と刺さりました。
GitHubで3,200スター以上を獲得しているこのライブラリ、実際に使ってみたら期待以上だったので紹介します。
Basecoatとは
BasecoatはTailwind CSSで構築されたUIコンポーネントライブラリです。shadcn/uiと同等の美しいデザインを、Reactなしで実現できるのが最大の特徴。
公式サイトでは「A components library built with Tailwind CSS that works with any web stack」と説明されています。つまり、PHPでもPythonでも、Go製のテンプレートエンジンでも、どんな環境でも動く。
現在のバージョンは0.3.6で、MITライセンスのオープンソース。40以上のコンポーネントを備えています。
正直なところ、「React使わない人向けのshadcn/ui」という理解で間違いないですね。
特徴・メリット
1. ランタイムJavaScriptがほぼ不要
これが個人的に一番刺さったポイント。Basecoatは基本的にCSSベースで動作するので、JavaScriptのバンドルサイズを気にする必要がない。
ドロップダウンメニューやポップオーバーなど、インタラクティブな6コンポーネントだけJavaScriptが必要ですが、それ以外は純粋なCSSで完結します。
30代になって思うのは、パフォーマンスへの意識って年々高まってくるんですよね。コスパ的に、軽量なライブラリはありがたい。
2. フレームワーク非依存
Laravel、Django、Rails、WordPress、素のHTMLサイト。どれでも使えます。
「このプロジェクトはReactじゃないから...」という理由で妥協したUI選択をしなくて済む。これ、意外と大きいです。
3. shadcn/uiテーマと完全互換
shadcn/uiで作ったカスタムテーマをそのまま使えます。チームでReactプロジェクトとそれ以外が混在している場合でも、デザインの一貫性を保てる。
@import "tailwindcss";
@import "basecoat-css";
@import "./theme.css"; /* shadcn/uiテーマをそのまま流用 */
4. クラス名がシンプル
Tailwindの長いクラス名地獄から解放される。btnとかinputとか、直感的なクラス名でスタイリングできます。
<!-- これだけでボタンが完成 -->
<button class="btn">Click me</button>
5. ダークモード標準対応
Tailwind CSSの設定を尊重するので、既存のダークモード実装とシームレスに連携できます。
インストール方法
CDNで手軽に始める(おすすめ)
HTMLファイルの<head>に2行追加するだけ。
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/basecoat-css@0.3.6/dist/basecoat.cdn.min.css">
<script src="https://cdn.jsdelivr.net/npm/basecoat-css@0.3.6/dist/js/all.min.js" defer></script>
これだけで全コンポーネントが使えるようになります。時短になるので、プロトタイプや小規模プロジェクトにはこれ一択ですね。
特定のコンポーネントだけ使う
バンドルサイズを削りたい場合は、必要なJavaScriptだけ読み込む方法も。
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/basecoat-css@0.3.6/dist/basecoat.cdn.min.css">
<script src="https://cdn.jsdelivr.net/npm/basecoat-css@0.3.6/dist/js/basecoat.min.js" defer></script>
<script src="https://cdn.jsdelivr.net/npm/basecoat-css@0.3.6/dist/js/dropdown-menu.min.js" defer></script>
npm / pnpm / yarn / bunでインストール
本格的なプロジェクトなら、パッケージマネージャーで管理した方がいいでしょう。
# npmの場合
npm install basecoat-css
# pnpmの場合
pnpm add basecoat-css
# bunの場合
bun add basecoat-css
CSSへのインポート
@import "tailwindcss";
@import "basecoat-css";
JavaScriptのインポート(ESM対応プロジェクト)
// 全コンポーネント
import 'basecoat-css/all';
// 個別インポート
import 'basecoat-css/basecoat';
import 'basecoat-css/popover';
import 'basecoat-css/tabs';
基本的な使い方
ボタン
<!-- 基本のボタン -->
<button class="btn">Default</button>
<!-- バリエーション -->
<button class="btn btn-secondary">Secondary</button>
<button class="btn btn-outline">Outline</button>
<button class="btn btn-ghost">Ghost</button>
<button class="btn btn-destructive">Destructive</button>
<button class="btn btn-link">Link</button>
クラス名を追加するだけでスタイルが変わる。シンプルでいいですよね。
サイズ指定
<button class="btn btn-sm">Small</button>
<button class="btn">Default</button>
<button class="btn btn-lg">Large</button>
カード
<div class="card">
<div class="card-header">
<h3 class="card-title">プロジェクト作成</h3>
<p class="card-description">新しいプロジェクトを作成します</p>
</div>
<div class="card-content">
<p>プロジェクトの詳細を入力してください。</p>
</div>
<div class="card-footer">
<button class="btn">作成</button>
</div>
</div>
フォーム入力
<div class="space-y-4">
<div>
<label class="label" for="email">メールアドレス</label>
<input type="email" id="email" class="input" placeholder="email@example.com">
</div>
<div>
<label class="label" for="password">パスワード</label>
<input type="password" id="password" class="input">
</div>
<button class="btn w-full">ログイン</button>
</div>
バッジ
<span class="badge">Default</span>
<span class="badge badge-secondary">Secondary</span>
<span class="badge badge-outline">Outline</span>
<span class="badge badge-destructive">Error</span>
ドロップダウンメニュー(JS必須)
<div class="dropdown-menu">
<button class="btn btn-outline dropdown-menu-trigger">
メニューを開く
</button>
<div class="dropdown-menu-content">
<div class="dropdown-menu-item">プロフィール</div>
<div class="dropdown-menu-item">設定</div>
<div class="dropdown-menu-separator"></div>
<div class="dropdown-menu-item">ログアウト</div>
</div>
</div>
実践的なユースケース
管理画面のサイドバー
<aside class="sidebar">
<div class="sidebar-header">
<span class="font-semibold">管理画面</span>
</div>
<nav class="sidebar-content">
<a href="#" class="sidebar-item sidebar-item-active">
ダッシュボード
</a>
<a href="#" class="sidebar-item">
ユーザー管理
</a>
<a href="#" class="sidebar-item">
設定
</a>
</nav>
<div class="sidebar-footer">
<button class="btn btn-ghost w-full">ログアウト</button>
</div>
</aside>
ダイアログ(モーダル)
<div class="dialog">
<button class="btn dialog-trigger">ダイアログを開く</button>
<div class="dialog-content">
<div class="dialog-header">
<h2 class="dialog-title">確認</h2>
<p class="dialog-description">この操作を実行してもよろしいですか?</p>
</div>
<div class="dialog-footer">
<button class="btn btn-outline dialog-close">キャンセル</button>
<button class="btn">確認</button>
</div>
</div>
</div>
Tailwindクラスでのオーバーライド
Basecoatのスタイルはあくまでベース。Tailwindのクラスを追加すれば簡単にカスタマイズできます。
<!-- フォントを細くする -->
<button class="btn font-normal">Click me</button>
<!-- 角を丸くする -->
<div class="card rounded-2xl">...</div>
<!-- 影を強調 -->
<div class="card shadow-lg">...</div>
CLIでテンプレート生成(Jinja/Nunjucks向け)
npx basecoat-cli add dialog
このコマンドでJavaScriptとマクロテンプレートが自動生成されます。Jinja2やNunjucksを使っているプロジェクトでは重宝しますね。
shadcn/uiとの使い分け
正直なところ、どちらを選ぶかは技術スタックで決まります。
| 項目 | Basecoat | shadcn/ui |
|---|---|---|
| 必須環境 | Tailwind CSS | React + Tailwind CSS |
| インストール | CDN / npm | CLIでコピー |
| JavaScript | 最小限 | React依存 |
| カスタマイズ | Tailwind / CSS変数 | ソースコード直接編集 |
| テーマ互換性 | shadcn/uiと互換 | 本家 |
| 向いている用途 | 非React環境 | Reactプロジェクト |
個人的には、Reactプロジェクトならshadcn/ui、それ以外ならBasecoat、という使い分けをしています。
デザインの統一感を保ちながら、技術スタックに合わせて選択できるのは嬉しいですね。
まとめ
Basecoatを導入して感じた変化:
- 技術選択の自由: React以外でもshadcn/ui品質のUIが使える
- 軽量: ランタイムJSがほぼ不要でパフォーマンスに優しい
- 学習コスト: Tailwind知っていればすぐ使える
- 互換性: 既存のshadcn/uiテーマをそのまま流用できる
- 導入の手軽さ: CDN2行で即使える
「Reactじゃないけど、きれいなUI欲しい」という人には刺さるはず。特にLaravel、Django、WordPressなどの伝統的なスタックで開発している人は、一度試してみる価値があると思いますよ。
40以上のコンポーネントが揃っているので、管理画面やLPなど、業務で必要になるUIパーツはほぼカバーできる印象です。
公式サイトにはキッチンシンクデモもあるので、各コンポーネントの見た目を確認してから導入を検討してみてください。