自分のデザインシステムを作る
プロダクトに置くのはレイヤファイル 1 つ。コマンド 1 つで、出荷する全プラットフォーム分のトークンとコードが 1 つのプルリクエストに揃います。
プロダクトの見た目を変えても、Tanrei のコンポーネントは変わりません。変わるのはレイヤです — 共通の語彙の「値」を決め、自分のパレットを宣言する小さな JSON ファイル。@tanrei/cli がその 1 ファイルを、各プラットフォームが必要とするものすべてに変換します。
プレリリース
0.1.0-next.0 を npm の dist-tag next で公開しています。0.1.0 までは @tanrei/cli@next、@tanrei/mcp@next をインストールしてください。0.x のプレリリースのあいだは後方互換を保ちません。どのプレリリースも、先に非推奨の期間を置くことなく何でも壊すことがあり、何を壊したかはその changeset に書いてあります。
コマンドラインツールを、プロダクトに開発用の依存として加えます。このページの npx tanrei … のコマンドは、どれもそれを実行します。tanrei studio が配信する Theme Studio も入っています。
npm install --save-dev @tanrei/cliMCP サーバーはインストールしなくてかまいません。このページの後のほうで登録するとおり、エージェントが起動するときに npx が @tanrei/mcp を取ってきます。
main のソースを使うには、リポジトリのクローンで 2 つのパッケージをビルドし、パックしたファイルをプロダクトに開発用の依存としてインストールします。
git clone https://github.com/chnotchy/tanrei.git
cd tanrei
pnpm install
pnpm --filter @tanrei/studio build:app # `tanrei studio` が配信する Theme Studio
pnpm --filter @tanrei/cli --filter @tanrei/mcp build
pnpm --filter @tanrei/cli --filter @tanrei/mcp pack --pack-destination ../tanrei-packages# プロダクトで:パッケージを書き出したフォルダーへのパス
npm install --save-dev path/to/tanrei-packages/tanrei-cli-*.tgz path/to/tanrei-packages/tanrei-mcp-*.tgzMCP サーバーは、npm のものの代わりにインストールしたものを登録します。プロダクトのフォルダーで claude mcp add tanrei -- npx tanrei-mcp を実行してください。
-
レイヤを作る — 既定のシステムか、プリセットから始めます。
npx tanrei init acme --extends tanreidesign/acme.system.jsonとtanrei.jsonが作られます。スライダーで作りたい場合は Theme Studio で形を決めてダウンロードしてください。 -
出力先を決める —
tanrei.jsonに、出荷するものだけを書きます。{ "system": "design/acme.system.json", "kotlinPackage": "com.acme.design", "outputs": { "tokens": "design/tokens/acme", "web": "apps/web/src/styles", "swiftui": "apps/ios/Acme/Design", "compose": "apps/android/app/src/main/kotlin/com/acme/design", "flutter": "apps/flutter/lib/design", "react-native": "apps/mobile/src/design" } } -
ビルドする。
npx tanrei build結果をコミットします。CI には
npx tanrei build --checkを入れてください。何も書き込まず、コミット済みの出力が古ければ失敗します。 -
使う。 生成されるのはあなたのシステムの「値」だけで、型はライブラリ側にあります。語彙が変わったときは、黙ってずれるのではなくビルドが壊れます。
プラットフォーム 生成物 書くコード Web acme.css<html data-tanrei-system="acme">SwiftUI TanreiSystem+Acme.swift.tanreiTheme(TanreiTheme(system: .acme))Compose TanreiSystemAcme.ktTanreiTheme(system = TanreiSystem.Acme) { … }Flutter acme_system.g.dartTanreiTheme(data: TanreiThemeData.platform(context, system: acmeSystem), …)React Native acme.ts<TanreiProvider system={acme}>
レイヤの値を 1 つ変えて tanrei build を実行すると、全プラットフォームのファイルが同じコミットで変わります。文字を全体的に少し大きくするのは 1 行です。
"tanrei.dial.type.base": { "$value": { "value": 17, "unit": "px" }, "reason": "腕を伸ばした距離で読まれるため。" }レイヤにできる 4 つのこと(ダイヤルを設定する/トークンを倍率で変える/参照先を差し替える/理由を添えて値を固定する)と、ブランドカラーやクイズの「正解・不正解」のようなパレットの宣言、そして値だけでは足りないときにトークンを足す方法は、デザインシステムとカスタマイズを参照してください。
カスタマイズは階層になっていて、どの階層も同じ <id>.system.json を編集します。
| やりたいこと | 使うもの |
|---|---|
| 手早くセットアップ | Theme Studio → レール:見た目の 9 行(ブランドカラー、グレー、書体、サイズ、角丸、角のスムージング、アイコン、押したときの表現、フォーカスの表示)を、それぞれ 1 回押すだけで。ロックとシャッフル付き |
| グループ単位で調整 | Studio → レールの「さらに細かく」:8 つのダイヤル、すべてのパレット、コンポーネントごと、すべてのふるまい |
| トークンを 1 つずつ GUI で | Studio → インスペクト → トークン:語彙全体を検索。各トークンには「そのトークンに合法な編集」だけが提示され、何が追従するかも分かります |
| ソースを編集 | Studio → インスペクト → ソース、またはお使いのエディター:JSON をスキーマとエンジンの両方で検証 |
| 存在しないトークンが欲しい | 足します:系列の段、Button のサイズや variant を 1 行で、あるいは自分のトークン |
npx tanrei studioは Theme Studio をあなたのレイヤファイルに対して開きます。編集はそのままファイルに保存され(他の変更と同じく git でレビューできます)、同時にエディターで行った編集を上書きすることはなく、「ビルド」で tanrei build が走ります。127.0.0.1 だけで待ち受け、表示されるリンクには使い捨てのキーが入っています。このサイトの Studio は同じツールで、ファイルの代わりに読み込み/書き出しを使います。
npx tanrei audit srcは、プロダクトのコード — スクリプト(JS、TS、JSX)、マークアップ(HTML、Vue、Svelte、Astro)、スタイルシート(CSS、Sass、Less)— を読み、あなたのシステムにないものを、ファイル・行・列と、代わりに書くものとともに報告します。
- システムにないコンポーネントの要素 — ページ、テンプレート、JSX、文字列の中の
<tanrei-fab-menu>、import した React のラッパー、それを指す CSS セレクタ。同じ役目でシステムが出荷するコンポーネント、それを持つシステム、それを取り込むためにレイヤに書く 1 行を添えます。 - システムに合わないエントリーからの import — 既定のシステムのプロダクトでの
@tanrei/web/m3-likeや@tanrei/react/all。合うエントリーを添えます。 - システムが外している
variant="…"の直書き。システムが提供する値を添えます。
照らし合わせる相手は、プロダクトのシステム(tanrei.json)か、--system で指定したもの(m3-like のような同梱のシステム、またはレイヤファイル)です。ファイル、ディレクトリ、または引用符で囲んだ glob('src/**/*.{ts,tsx,html,css}')を渡します。ディレクトリは node_modules と隠しディレクトリを除いて読みます。--format json は結果をデータとして出力します。何か見つかれば終了コード 1 で終わるので、CI で tanrei build --check と並べて走らせられます。実行できなかったときは 2 です。MCP サーバーの check_usage も同じ検査を行います。
読むのはテキストで、動いているページではありません。コメントは読み飛ばしますが、変数に入れた variant や、部品から組み立てたタグ名は見えません。
outputs に "tailwind" や "shadcn" を足します。どちらのファイルも Tanrei のカスタムプロパティへ名前を対応づけるだけなので、テーマ、コントラスト、実行時のダイヤルはそのまま機能します。
@import "tailwindcss";
@import "@tanrei/web/tokens.css";
@import "./styles/acme.css";
@import "./styles/acme.tailwind.css"; /* bg-primary · text-on-primary · rounded-medium · p-200 · text-heading-4 */-
tokensの出力は、標準のリゾルバを備えた自己完結の DTCG 2025.10 バンドルです。どのデザイントークンツールでも読めます。生成元のレイヤファイルも中に入っており、各グループには AI エージェント向けの使い方($extensions["dev.tanrei.llm"])が付いています。 -
その中には
components.jsonもあります。あなたのシステムが出荷するコンポーネントの一覧で、それぞれの要素名(またはクラス名)、React での名前、登録するモジュールが書かれています。出荷しないコンポーネントも、どのレイヤが外したか、代わりに何を使うかとともに載っています。これを読むエージェントは、あなたのプロダクトで使えるコンポーネントだけを提案します。同梱の各システムにも 1 つずつあります(@tanrei/web/systems/<id>.components.json)。 -
@tanrei/mcpは
Model Context Protocol のサーバーです。あなたのリポジトリで作業するエージェントは、語彙を検索し、値がどこから来たかを調べ、システム同士を比較し、拡張を提案(新しい Button サイズ、系列の段、自分のトークン)してその結果の値を確かめ、レイヤの編集を書き込む前に検証できます。エージェントにはルールも伝えられます — 値はレイヤで変える、語彙の拡張は追加のみ・理由つき、固定する値には理由を書く、閾値には触れない。UI そのものについては、システムのコンポーネントマニフェストと仕様から答えます — そのシステムにあるコンポーネント(ないものには代わりに使うもの)、コンポーネントの props、イベント、振る舞いの規則、そしてコードの中でそのシステムにない要素、import、variant とその位置(tanrei auditと同じ検査です)。プロダクトのフォルダーで、npm から登録します(ほかのクライアントの設定は AI エージェントと Tanrei を使う にあります)。
claude mcp add tanrei -- npx -y @tanrei/mcp
アクセシビリティ
コントラストの閾値と構造チェックは定数です。あなたのレイヤでの違反は警告になりますが、黙殺はされません — tanrei build が表示し、a11y-report.json に書き込み、生成ファイルの先頭にも記されます。中・高コントラストは利用者がコントラストを求めた結果なので、そこでは 0 件を目指してください。なお、同梱のプリセットそのものは模倣元への忠実さで評価し、どのスキームでも Tanrei のアクセシビリティ基準は適用しません。その計測値は参考情報です。プリセットの上に作ったレイヤはあなたのプロダクトなので、継承した分も警告されます。