Ginga UIは、LLMに配色・角丸・枠線・フォントのCSS変数を作らせて見た目を決める、React向けのUIコンポーネントライブラリです。作者はnewt239氏で、MITライセンスのOSSとして @ginga-ui/core と @ginga-ui/utils の2パッケージで配布されています。この記事は2026年10月1日時点の最新版0.14.0(2026年8月18日公開)の配布物を読み、手元で動かした結果をもとに、主な機能・導入手順・テーマ生成の仕組み・採用前に知っておくべき制約をまとめます。
なお、ネット上には npm install gingaui や ThemeProvider を使う解説がありますが、gingaui というパッケージはnpmに存在せず、ThemeProvider というコンポーネントもありません。正しい導入方法は後半の手順を参照してください。
まとめ:Ginga UIの要点
- Ginga UIは、React Aria Components 1.20.0の上に作られたReact 18以上向けのUIライブラリです。0.14.0では26種のコンポーネントを提供します。
- 最大の特徴は
ThemeClientです。プロンプトを渡すとLLMが6つのCSS変数を返し、主色と文字色からはそれぞれ10段階の色階調が自動で作られます。 - LLMはOpenAI・Google・Anthropicに加え、0.14.0からブラウザ内蔵モデル(APIキー不要)も選べます。ChromeではGemini Nanoが使われます。
- 生成した色は、背景とのコントラスト比3.0超えを目標に再生成・補正されます。ただし中間色の背景では届かないことがあり、3.0自体も本文テキストに求められる4.5より低いため、本文に使う色は別途確認が必要です。
- 導入は
npm install @ginga-ui/coreとvariables.cssの読み込みだけです。旧パッケージ名ginga-uiは2025年3月1日に取り下げられています。 - 0.x系の個人開発で、npmのダウンロードは月42件(2026年8月31日〜9月29日)です。試作やデザイン検討には向きますが、長期保守する業務システムの基盤には勧めません。
Ginga UIの開発元・版・配布状況
GitHubのREADMEの説明は「LLMを使ってコンポーネントをスタイリングするReactのUIライブラリ」です。この記事の仕様は、READMEとnpmの0.14.0の配布物で確認しています。名前は日本語の「銀河」に由来します。リポジトリは2024年9月11日に作られ、2026年9月30日まで更新が続いています。
| 項目 | 内容(2026年10月1日時点) |
|---|---|
| 最新版 | 0.14.0(2026年8月18日公開) |
| パッケージ | @ginga-ui/core(部品)・@ginga-ui/utils(テーマ生成) |
| 動作要件 | React 18以上(peerDependencies) |
| 土台 | react-aria-components 1.20.0(版固定) |
| LLM呼び出し | Vercel AI SDK(ai 7.0.59) |
| ライセンス | MIT |
| GitHub | スター38・フォーク0・コミット606件 |
| npmダウンロード | 月42件(@ginga-ui/core) |
パッケージ名の変遷:ginga-uiから@ginga-ui/coreへ
最初の配布名はスコープなしの ginga-ui でした。0.0.0(2024年10月18日)から0.8.1(2025年1月30日)まではこの名前で公開されていました。0.9系で @ginga-ui スコープへ移り、0.9.1は2025年2月27日に公開されています。旧名の全版は2025年3月1日に取り下げられたため、いま npm install ginga-ui を実行すると「404 Unpublished on 2025-03-01」で失敗します。
ネット上の解説にある gingaui(ハイフンなし)はnpmに登録がなく、引くと取り下げ記録もない「404 Not Found」が返ります。インストール手順に gingaui や ginga-ui が書かれた記事は、現行版の説明として読まないでください。
Ginga UIの主な機能:0.14.0のコンポーネント26種
0.14.0の @ginga-ui/core が提供するコンポーネント群を、公式ドキュメントの5分類で並べると次のとおりです。CodeBlockだけはドキュメントの一覧に載っていないため、末尾に別記しました。
| 分類 | コンポーネント |
|---|---|
| フォーム(8) | Button・Checkbox・Input・Radio・Select・Slider・Switch・FormControl |
| 表示(13) | Accordion・Alert・AlertDialog・Badge・Card・Dialog・Drawer |
| Image・List・Popover・Table・Tab・Toast | |
| タイポグラフィ(2) | Heading・Paragraph |
| ナビゲーション(1) | Anchor |
| レイアウト(1) | Box |
| 一覧外(1) | CodeBlock(0.14.0で追加) |
公式サイトのトップには「19個のコンポーネント」とありますが、これは0.13系までの数字です。0.14.0でAlertDialog・Drawer・Popover・Alert・Badge・Toast・CodeBlockの7種が加わりました。
逆に、ナビゲーションバー・サイドバー・ドロップダウンメニュー・アバター・アイコン・グリッドに当たるコンポーネントはありません。ContainerとFlexは0.7.11で削除され、代わりにBoxが入っています。ライト/ダークを切り替える仕組みも同梱されておらず、配布物のCSSには prefers-color-scheme が1か所も出てきません。暗い配色にしたいときは、背景色を含むCSS変数そのものを差し替えます。
React Aria由来のprops:isDisabledではなくdisabled
Button・Checkbox・Dialogなどの中身は、React Aria Componentsの部品にGinga UIのクラスとCSSをかぶせたものです。キーボード操作やフォーカス管理はReact Ariaの実装をそのまま使います。押下イベントも onClick ではなく onPress が基本です。
ただし、無効化のpropsだけはReact Ariaと名前が違います。Buttonの型はReact Ariaの isDisabled を除外し、代わりに disabled を受け取ります。React Ariaの書き方のまま <Button isDisabled> と書くと、TypeScript 7.0.2では「Did you mean ‘disabled’?」というTS2322エラーになりました。Buttonの variant は filled・light・outline・reverse の4種です。
Ginga UIのインストールと最小構成
READMEが推奨する環境は、React 18以上、Next.js 13以上(App Router推奨)、React Router v7、Vite構成のReactです。導入は次の2行です。
npm install @ginga-ui/[email protected]
# テーマ生成も使う場合
npm install @ginga-ui/[email protected]
ルートのコンポーネント(Next.js App Routerなら app/layout.tsx)で、既定テーマのCSS変数を1回だけ読み込みます。各コンポーネントのCSSは、コンポーネントをimportした時点で自動的に読み込まれます。
// app/layout.tsx
import "@ginga-ui/core/variables.css";
あとは部品をimportして使います。次のコードは0.14.0の型定義に対してtscが通ることを確認しています。
"use client";
import { Button, Card, Heading, Paragraph } from "@ginga-ui/core";
export default function Home() {
return (
<Card>
<Heading level="h2">はじめての Ginga UI</Heading>
<Paragraph>テーマはCSS変数で切り替わります。</Paragraph>
<Button variant="filled" onPress={() => console.log("pressed")}>
保存する
</Button>
<Button variant="outline" disabled>
送信できません
</Button>
</Card>
);
}
このコンポーネントをサーバー側でレンダリングすると、Buttonは class="ginga-button" と data-variant="filled" を持つ <button type="button"> になりました。無効化したボタンには disabled と data-disabled="true" が付きます。CSSは .ginga-button や data-variant を手がかりに上書きできます。onPress のような関数をpropsで渡すため、App Routerではこのファイルに "use client" が必要です。
Node.js直接実行時のCSS importエラー
0.13.3以降は、各コンポーネントのJSが自分のCSSを import "./index.css" で読み込む構成です。そのため、Next.jsやViteを通さずに素のNode.jsで @ginga-ui/core をimportすると、ERR_UNKNOWN_FILE_EXTENSION(拡張子 .css を解釈できない)で止まります。テストやスクリプトで使う場合は、CSSを空として扱うローダーを設定してください。esbuildなら --loader:.css=empty で回避できました。コンポーネントの各ファイル(Boxを除く)の先頭には "use client" が付いており、App RouterのServer Componentからそのまま読み込めます。
ThemeClientによるテーマ生成の仕組み
テーマ生成は @ginga-ui/utils の ThemeClient が担います。0.14.0の実装を読むと、処理は次の4段階です。
- Vercel AI SDKの
generateObjectでLLMを呼び、Zodのスキーマに合う6変数のJSONを受け取る - 主色・文字色と背景色のコントラスト比が両方とも3を超えるか検証する。生成と検証は初回を含め既定で最大3回行う
- 最後の試行でも足りなければ明暗を補正する。ただし改善停止や反復上限でも終了し、補正後も3未満になる場合がある
- 背景色から主色・文字色へ向かう10段階の階調を作り、
:root { ... }形式のCSS文字列として返す
LLMが決める6つのCSS変数と10段階の色階調
| 変数 | 役割 | 既定値 |
|---|---|---|
--color-primary |
アクセント色 | #1677ff |
--color-secondary |
本文の文字色 | #000000 |
--color-background |
背景色 | #ffffff |
--width-border |
枠線の太さ | 2px |
--size-radius |
角丸 | 1rem |
--font-family |
フォント | sans-serif |
主色と文字色からは、それぞれ -0 から -9 までの10段階の階調が作られます。生成後の -0 は背景色そのもの、-9 は主色・文字色そのものです。コンポーネントのCSSで最も多く参照されているのは --color-primary-9(35か所)です。つまり、LLMが選んだ主色がボタンや強調表示にほぼそのまま使われます。
0.14.0で加わった --color-info・--color-success・--color-warning・--color-danger の意味色は、variables.css の固定値です。LLMの生成対象には含まれないため、背景を暗くしたテーマでは自分で調整する必要があります。
プロバイダーと既定モデル
| provider | 既定モデル | APIキー(環境変数) |
|---|---|---|
openai |
gpt-5.6-luna | OPENAI_API_KEY |
google |
gemini-3.7-flash | GOOGLE_GENERATIVE_AI_API_KEY |
anthropic |
claude-haiku-4-5 | ANTHROPIC_API_KEY |
browser |
ブラウザ内蔵モデル(環境依存) | 不要 |
model には、選択したOpenAI・Google・Anthropicプロバイダーで利用でき、テーマ生成に必要な構造化出力に対応するモデルを指定します。browser は0.14.0で加わった指定で、0.13.3の依存関係には含まれていません。ブラウザのPrompt APIを呼ぶため、対応するブラウザ上(Client Component)でしか動かず、model の指定も無視されます。READMEは「ChromeとEdgeに搭載されたGemini Nano」と説明していますが、Microsoftの開発者向け資料によると、EdgeのPrompt APIが使うのはPhi-4-miniです(Canary・Dev版)。初回は数GBのモデルのダウンロードが走るので、getBrowserAIAvailability() の戻り値が "unavailable" のときはクラウドのプロバイダーへ切り替えます。
GitHubのmainブランチには、コンストラクタで apiKey を直接渡せるようにする変更が2026年9月21日に入っています。ただし0.14.0の型定義の引数は provider と model だけで、まだnpm版では使えません。
コントラスト比3.0の検証と自動補正
判定にはchroma-jsのコントラスト比(WCAGと同じ計算式)が使われ、基準は「3より大きい」です。補正処理(enforceContrast)を0.14.0とNode.js v26.5.0で単体実行した結果が次の表です。多くの色は3をわずかに超えた時点で止まりました。ただし、補正は「比率が改善しなくなった」「100回繰り返した」ときにも打ち切られ、その後の再検証はありません。背景が中間色の#999999だと3に届かず、補正前より比率が下がる例もありました。
| 背景色 | 入力色(比) | 補正後(比) |
|---|---|---|
| #ffffff | #bbbbbb(1.92) | #949494(3.03) |
| #ffffff | #ffd400(1.43) | #b29000(3.05) |
| #101828 | #334155(1.71) | #59677d(3.09) |
| #fff8e7 | #f4a261(1.95) | #c87c3d(3.10) |
| #999999 | #999999(1.00) | #ffffff(2.85) |
| #999999 | #888888(1.24) | #8d8d8d(1.16) |
Ginga UIを採用する前に確認したい3つの制約
READMEやドキュメントには書かれていませんが、配布物を読んで動かすと分かる制約があります。どれもテーマ生成を本番の画面に直接つなぐと問題になる点です。
通常サイズの本文に必要な4.5:1と生成色の検証不足
WCAG 2.2の達成基準1.4.3は、通常サイズの文字に4.5:1以上、大きな文字に3:1以上のコントラスト比を求めています。3:1で足りるのは、大きな文字と、1.4.11のボタン枠などの非テキスト要素です。ところがGinga UIは、本文の文字色である --color-secondary も主色と同じ「3超え」で合格にします。上の表のとおり、白背景に対して #949494(3.03:1)が採用されることがあり、これは本文の文字としてはAA基準を満たしません。中間色の背景では3にすら届かない場合もあります。
アクセシビリティ要件がある画面では、生成結果の --color-secondary を自分で4.5以上か確かめてから使ってください。基準の適用範囲はWebアクセシビリティのコントラスト比の解説で詳しく扱っています。
テーマ生成失敗時のエラー戻り値と分岐処理
generateTheme は失敗しても例外を投げず、{ type: "error", CSSCode: "<エラーメッセージ>" } を返します。APIキーを設定せずにOpenAIを指定して実行すると、約0.1秒で type が "error"、CSSCode が「OpenAI API key is missing…」という文字列で返りました。公式のNext.jsの例は戻り値をそのまま <style>{CSSCode}</style> に入れているため、失敗するとエラー文がstyle要素に入ります。画面は variables.css の既定テーマのまま表示されるので、失敗に気づきにくくなります。必ず type を見て分岐してください。存在しないproviderを渡したときだけは、コンストラクタが Unsupported provider の例外を投げます。
生成配色の再現性とCSSファイルへの固定
LLMの出力は、同じプロンプトでも変わる可能性があります。公式のクイックスタートでは RootLayout の中で generateTheme を呼んでいますが、レンダリングのたびに生成が走る構成では、表示ごとに配色が変わるおそれがあり、そのたびにAPI料金もかかります。テーマ生成はデザイン案を出す道具と割り切り、気に入った結果をCSSファイルに保存して固定するのが現実的です。
// scripts/theme.ts(ビルド前に1回だけ実行する)
import { writeFile } from "node:fs/promises";
import { ThemeClient } from "@ginga-ui/utils";
const client = new ThemeClient({ provider: "anthropic" });
const result = await client.generateTheme("和紙と墨の落ち着いた雰囲気");
if (result.type === "error") {
console.error("テーマ生成に失敗:", result.CSSCode);
process.exit(1);
}
await writeFile("app/theme.css", result.CSSCode);
保存した theme.css を variables.css の後に読み込めば、既定値が上書きされます。なお、ブラウザ上で generateTheme を呼ぶと、戻り値を返す前に document.documentElement のstyleへ全変数を直接書き込みます。ページ全体の配色がその場で切り替わる点も覚えておいてください。
Chakra UI・Material UIとの違いと使い分け
Ginga UIは、Chakra UIやMaterial UIの代わりになるライブラリではありません。部品の数と利用規模が大きく違うため、比べるならテーマの決め方で比べるべきです。npm月間DLは2026年8月31日〜9月29日の値です。
| 観点 | Ginga UI | Chakra UI | Material UI |
|---|---|---|---|
| 最新版(2026年10月1日) | 0.14.0 | 3.37.0 | 9.4.0 |
| テーマの決め方 | LLMがCSS変数6つを生成 | トークンを設計して定義 | Material Designに沿って調整 |
| レイアウト部品 | Boxのみ | Stack・Grid等 | Grid・Stack等 |
| ダークモード | 切替機構なし | next-themes連携 | あり |
| npm月間DL | 42 | 約687万 | 約4,178万 |
業務アプリの画面を長く保守するなら、Chakra UIのv3やMaterial UIのv9系のほうが安全です。Ginga UIが向くのは、ハッカソンの試作、ブランドが未定の段階での配色案出し、LLMにデザインを任せる仕組みの検証です。UIの構造そのものをLLMに生成させたいなら、Generative UIのフレームワークが別の選択肢になります。
よくある質問
Ginga UIは無料で使えますか?
ライブラリ自体はMITライセンスで無料です。ただしテーマ生成でOpenAI・Google・Anthropicを使う場合は、各社のAPI料金がかかります。ブラウザ内蔵モデルを使う provider: "browser" なら、クラウドAPIの従量料金はかかりません。
Ginga UIのインストールコマンドは?
npm install @ginga-ui/core です。テーマ生成も使う場合は、@ginga-ui/utils も入れます。gingaui はnpmに存在しない名前で、ginga-ui は2025年3月1日に取り下げられたため、どちらも404で失敗します。
Next.jsのApp Routerで使えますか?
使えます。READMEはNext.js 13以上のApp Routerを推奨環境に挙げており、コンポーネントのファイルには "use client" が付いています。app/layout.tsx で variables.css を読み込んでください。テーマ生成はAPIキーを隠せるサーバー側で行うのが推奨です。
Ginga UIはダークモードに対応していますか?
切り替えの仕組みは同梱されていません。背景色の --color-background を暗くしたテーマを生成するか、自分で用意したCSS変数を上書きして実現します。意味色(info・success・warning・danger)は固定値なので、暗い背景では個別に調整が必要です。
Ginga UIにはどんなコンポーネントがありますか?
0.14.0ではフォーム8種、表示13種、タイポグラフィ2種、ナビゲーション1種、レイアウト1種に、CodeBlockを加えた計26種です。ナビゲーションバー、サイドバー、アイコン、グリッドはありません。