Meta、AI対応デザインシステム「Astryx」を公開
Meta は、人間と AI エージェントの両方に対応可能な「Astryx」というオープンソースの React デザインシステムをベータ版として公開し、150 以上のアクセシブルなコンポーネントと CLI を提供した。
キーポイント
AI エージェント対応設計
従来のデザインシステムが人間中心だったのに対し、Astryx は AI エージェントとの連携を前提とした設計となっており、両者が協働して操作できることを目指している。
柔軟なテーマと分離アーキテクチャ
動作やアクセシビリティはシステムが制御し、見た目は CSS カスタムプロパティによるトーンで制御する「分離」アプローチを採用し、フォークなしでのカスタマイズを可能にしている。
技術的実装の簡素化
React と StyleX を基盤としつつ、ビルドプラグインや独自のスタイリングライブラリの導入不要で、既存のプロジェクト(Tailwind や CSS Modules など)と容易に統合できる。
8 年の内部開発の結晶
Meta 内で過去 8 年にわたり開発・運用され、最も使用頻度が高く大規模なデザインシステムとして成熟した成果をオープンソース化したものである。
150 以上のアクセシブルコンポーネントと 7 つのテーマ
Astryx は、視覚的・機能的な多様性を提供するため、150 個以上のアクセシビリティ対応コンポーネントと 7 つの異なるテーマを標準で備えています。
エージェント対応設計と CLI ツールの統合
本システムは AI エージェントによる自動生成や操作に最適化されており、開発効率を高めるための専用 CLI(コマンドラインインターフェース)も提供されています。
CSS変数による高度なカスタマイズ性
Astryxは、色やサイズを定義する CSS 変数(例:--pv-primary, --pv-radius)を活用し、7 つのテーマやアクセシビリティ設定を容易に切り替えられる設計となっています。
重要な引用
Astryx, an open source design system that is fully customizable and built to be operated by both people and the AI agents working alongside them.
The system controls behavior, accessibility, and quality. Themes control how it looks.
Components are composed at any level rather than locked behind a closed top-level API, and swizzle can eject a component's full source into your project when you need to own it.
Meta Open-Sources Astryx: An Agent-Ready React Design System With 150+ Accessible Components, Seven Themes, and a CLI
Astryx is an agent-ready design system with over 150 accessible components.
An Agent-Ready React Design System With 150+ Accessible Components, Seven Themes, and a CLI
影響分析・編集コメントを表示
影響分析
この発表は、AI エージェントがソフトウェア開発や UI 操作に深く関与する未来において、人間と AI が共通の言語(デザインシステム)で協働するための基盤を提供した点で画期的です。特に、フォークやラッパーなしでのカスタマイズを可能にするアーキテクチャは、オープンソースコミュニティにおける標準化と個別最適化の長年のジレンマに対する実用的な解決策を示しています。
編集コメント
「人間と AI が共に操作する」というコンセプトは、単なる自動化ツールを超えて、AI を開発プロセスの対話型パートナーとして組み込むための重要な一歩です。特に、フォークなしでテーマを適用できる仕組みは、大規模なエコシステムにおける標準化とブランドの一貫性を保ちつつ、各社の独自性を維持する現実的な解として注目されます。
Meta は、人間と AI エージェントの両者が協働して運用できるフルカスタマイズ可能なオープンソース・デザインシステム「Astryx」をベータ版として公開しました。これは新規の実験プロジェクトではなく、過去 8 年間に Meta 内部で育まれてきたものです。同社によると、毎日エンジニアやデザイナー、プロダクトチームに支えられ続けられた結果、現在では最も利用頻度が高く、規模も最大のデザインシステムへと成長したとのことです。
Astryx は、150 以上のアクセシビリティ対応コンポーネント(ドキュメントサイト上では 160 以上)、ブランドレベルのテーマ設定、ダークモード、すぐに使えるテンプレート、そして CLI を一つのまとまったパッケージとして提供します。基盤には React と StyleX が採用されており、事前にビルドされた CSS をインポートして、型安全な React コンポーネントを使用できます。接続用のビルドプラグインを導入する必要もあれば、独自のスタイリングライブラリを採用する必要もありません。
Astryx が解決しようとしている課題
多くのデザインシステムでは、どちらか一方を選ばざるを得ないジレンマがあります。大企業のシステムを採用すれば、自社のアプリが他社製品そっくりの見た目になってしまうリスクがあります。逆に、コピー&ペーストでコンポーネントを流用すれば、各プロジェクトが独自のコードスニペットにフォークし、共通の整合性が失われ、外部からの修正も受け入れられず、アクセシビリティの問題は後回しになりがちです。
Astryx はこの 2 つの課題を分離して解決します。システム側で動作やアクセシビリティ、品質基準を管理し、見た目についてはテーマが担当します。色、フォント、角丸、モーションなどのトークンレベルでカスタマイズできるため、書き換えを行わずともアプリに独自性を持たせることが可能です。テーマは単なる CSS カスタムプロパティのオーバーライドの集合体であるため、デザイナーはコンポーネントソースをフォークしたりラップしたりすることなく、Astryx の見た目を自由に再設計できます。
Astryx の設計原則は、強制ではなくガイダンスを重視し、文書化された明確な規約に基づき、人間と AI が共通で利用する単一のシステムを実現すること、そして測定によってその価値を検証するという点にあります。つまり、規約は主張されるものではなく、実際にテストされて確立されるものです。
アーキテクチャは「基盤」「コンポーネント」「パターン」の 3 レイヤーで構成されています。基盤(Foundations)は、一貫性がありアクセシビリティに配慮したインターフェースを構築するための基本要素であり、タイポグラフィ、カラー、レイアウト、そしてアクセシビリティが含まれます。コンポーネントは、TypeScript のフルサポートを持つ 150 以上の再利用可能なビルディングブロックです。パターンは、テーブルページや詳細画面のレイアウト、フォームウィザード、ナビゲーション、データ入力フローなど、一般的なワークフローに対する実戦で検証された解決策を提供します。
このシステムが特にオープンである理由は、2 つの設計思想にあります。まず、コンポーネントは特定のトップレベル API に閉じ込められるのではなく、あらゆるレベルで組み合わせ可能である点です。また、必要に応じてコンポーネントのソースコードをプロジェクト内に直接取り込む「スウィズル(swizzle)」機能も用意されています。
スタイリングには StyleX が採用されていますが、これは利用者からは見えません。そのため、既存のプロジェクトに合わせて Tailwind、CSS Modules、あるいは通常の CSS を className で上書きすることが可能です。以下の解説では、トークンを変更するだけで Astryx の 7 つのテーマ間でコンポーネント群がどのように再スタイルされるかを示しています。
Astryx Explainer — Marktechpost
/* ===== Marktechpost · Astryx インタラクティブ解説 (ライトテーマ) ===== */
#mtp-ax-explainer *{box-sizing:border-box;margin:0;padding:0}
#mtp-ax-explainer{
--ink:#16181D; --ink-2:#5A6270; --ink-3:#8A9099;
--line:#E6E8EC; --paper:#FFFFFF; --tint:#F6F7F9;
--brand:#1657E0; --brand-ink:#0B3AA8; --ok:#16A34A;
--mono:ui-monospace,"SF Mono","JetBrains Mono",Menlo,Consolas,monospace;
--sans:"Inter Tight",Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;
font-family:var(--sans); color:var(--ink); background:var(--paper);
line-height:1.5; -webkit-font-smoothing:antialiased;
border:1px solid var(--line); border-radius:16px; overflow:hidden;
max-width:900px; margin:0 auto;
}
#mtp-ax-explainer .ax-head{padding:22px 24px 18px;border-bottom:1px solid var(--line);background:
linear-gradient(180deg,#FBFCFE,#FFFFFF)}
#mtp-ax-explainer .ax-eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.14em;
text-transform:uppercase;color:var(--brand);font-weight:600;display:flex;align-items:center;gap:8px}
#mtp-ax-explainer .ax-eyebrow::before{content:"";width:22px;height:2px;background:var(--brand);border-radius:2px}
#mtp-ax-explainer h2.ax-title{font-size:22px;line-height:1.2;letter-spacing:-.02em;margin:10px 0 4px;font-weight:700}
#mtp-ax-explainer .ax-sub{color:var(--ink-2);font-size:14px;max-width:60ch}
/* ステータスバー */
#mtp-ax-explainer .ax-stats{display:grid;grid-template-columns:repeat(6,1fr);gap:1px;background:var(--line);
border-bottom:1px solid var(--line)}
#mtp-ax-explainer .ax-stat{background:var(--paper);padding:14px 12px;text-align:center}
#mtp-ax-explainer .ax-stat b{display:block;font-size:20px;letter-spacing:-.02em;font-weight:700;color:var(--ink)}
#mtp-ax-explainer .ax-stat span{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.06em;
text-transform:uppercase;color:var(--ink-3);margin-top:3px}
#mtp-ax-explainer .ax-body{padding:22px 24px 8px}
#mtp-ax-explainer .ax-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:22px;align-items:start}
/* コントロール用スタイル */
#mtp-ax-explainer .ax-panel h3 { font-size: 12px; font-family: var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); margin-bottom: 10px; font-weight: 600 }
#mtp-ax-explainer .ax-themes { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px }
#mtp-ax-explainer .ax-chip { cursor: pointer; border: 1px solid var(--line); background: var(--paper); border-radius: 999px; padding: 6px 12px 6px 8px; font-size: 13px; font-weight: 500; display: flex; align-items: center; gap: 7px; transition: border-color .15s, box-shadow .15s, transform .06s; color: var(--ink) }
#mtp-ax-explainer .ax-chip:hover { border-color: #C9CED6 }
#mtp-ax-explainer .ax-chip .dot { width: 14px; height: 14px; border-radius: 50%; box-shadow: inset 0 0 0 1px rgba(0,0,0,.08) }
#mtp-ax-explainer .ax-chip[aria-pressed="true"] { border-color: var(--brand); box-shadow: 0 0 0 3px rgba(22,87,224,.12) }
#mtp-ax-explainer .ax-chip:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px }
#mtp-ax-explainer .ax-sliders{display:grid;gap:14px;margin-bottom:16px}
#mtp-ax-explainer .ax-slider label{display:flex;justify-content:space-between;font-size:13px;color:var(--ink-2);margin-bottom:6px}
#mtp-ax-explainer .ax-slider label b{font-family:var(--mono);color:var(--ink);font-weight:600}
#mtp-ax-explainer input[type=range]{width:100%;accent-color:var(--brand);height:4px;cursor:pointer}
#mtp-ax-explainer .ax-toggle{display:inline-flex;align-items:center;gap:9px;font-size:13px;color:var(--ink-2);cursor:pointer;user-select:none}
#mtp-ax-explainer .ax-sw{width:38px;height:22px;border-radius:999px;background:#D5D9E0;position:relative;transition:background .18s}
#mtp-ax-explainer .ax-sw::after{content:"";position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;
background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.25);transition:transform .18s}
#mtp-ax-explainer .ax-toggle[aria-pressed="true"] .ax-sw{background:var(--brand)}
#mtp-ax-explainer .ax-toggle[aria-pressed="true"] .ax-sw::after{transform:translateX(16px)}
/* トークンの読み出し */
#mtp-ax-explainer .ax-tokenbtn{margin-top:6px;font-family:var(--mono);font-size:12px;color:var(--brand);
background:none;border:none;cursor:pointer;padding:4px 0;text-decoration:underline;text-underline-offset:3px}
#mtp-ax-explainer .ax-tokens{margin-top:10px;background:#0E1116;border-radius:10px;padding:12px 14px;
font-family:var(--mono);font-size:12px;line-height:1.7;color:#C9D3E0;display:none;overflow-x:auto}
#mtp-ax-explainer .ax-tokens.show{display:block}
#mtp-ax-explainer .ax-tokens .k{color:#7FA6FF}
#mtp-ax-explainer .ax-tokens .v{color:#89E0B0}
/* live preview device */
#mtp-ax-explainer .ax-previewwrap{position:sticky;top:8px}
#mtp-ax-explainer .ax-device{border:1px solid var(--pv-line,#E6E8EC);border-radius:calc(var(--pv-radius,10px) + 6px);
background:var(--pv-bg,#fff);padding:16px;transition:background .25s,border-color .25s,border-radius .25s;
box-shadow:0 10px 30px -18px rgba(16,24,40,.35)}
#mtp-ax-explainer .ax-devbar{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}
#mtp-ax-explainer .ax-devdots{display:flex;gap:5px}
#mtp-ax-explainer .ax-devdots i{width:8px;height:8px;border-radius:50%;background:var(--pv-line,#E6E8EC);display:block}
#mtp-ax-explainer .ax-devtag{font-family:var(--mono);font-size:10px;color:var(--pv-muted,#8A9099);letter-spacing:.05em}
#mtp-ax-explainer .ax-card{background:var(--pv-surface,#F4F4F5);border:1px solid var(--pv-line,#E6E8EC);
border-radius:var(--pv-radius,10px);overflow:hidden;transition:all .25s}
#mtp-ax-explainer .ax-thumb{height:96px;background:
linear-gradient(135deg,var(--pv-primary,#18181B),color-mix(in srgb,var(--pv-primary,#18181B) 55%,#ffffff));
position:relative}
#mtp-ax-explainer .ax-badge{position:absolute;top:10px;left:10px;background:var(--pv-bg,#fff);color:var(--pv-primary,#18181B);
font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;padding:4px 8px;border-radius:999px}
#mtp-ax-explainer .ax-cardbody{padding:var(--pv-pad,14px)}
#mtp-ax-explainer .ax-cardbody h4{color:var(--pv-text,#18181B);font-size:15px;font-weight:700;margin-bottom:2px}
#mtp-ax-explainer .ax-cardbody p{color:var(--pv-muted,#6B7280);font-size:12.5px;margin-bottom:12px}
#mtp-ax-explainer .ax-row{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:12px}
#mtp-ax-explainer .ax-price{color:var(--pv-text,#18181B);font-weight:700;font-size:15px}
#mtp-ax-explainer .ax-input{flex:1;border:1px solid var(--pv-line,#E6E8EC);background:var(--pv-bg,#fff);
border-radius:calc(var(--pv-radius,10px) - 2px);padding:8px 10px;font-size:12.5px;color:var(--pv-text,#18181B);min-width:0}
#mtp-ax-explainer .ax-input::placeholder{color:var(--pv-muted,#9AA0AA)}
#mtp-ax-explainer .ax-btn{background:var(--pv-primary,#18181B);color:var(--pv-onprimary,#fff);border:none;
border-radius:calc(var(--pv-radius,10px) - 2px);padding:9px 14px;font-size:13px;font-weight:600;cursor:pointer;
font-family:var(--sans);white-space:nowrap;transition:filter .15s}
#mtp-ax-explainer .ax-btn:hover{filter:brightness(.94)}
#mtp-ax-explainer .ax-btn.ghost{background:transparent;color:var(--pv-primary,#18181B);
box-shadow:inset 0 0 0 1px var(--pv-primary,#18181B)}
#mtp-ax-explainer .ax-mini{display:flex;align-items:center;gap:8px;color:var(--pv-muted,#6B7280);font-size:12px}
#mtp-ax-explainer .ax-miniSw{width:32px;height:19px;border-radius:999px;background:var(--pv-primary,#18181B);position:relative;flex:none}
#mtp-ax-explainer .ax-miniSw::after{content:"";position:absolute;top:2px;right:2px;width:15px;height:15px;border-radius:50%;background:var(--pv-bg,#fff)}
#mtp-ax-explainer .ax-caption{margin-top:10px;font-size:11.5px;color:var(--ink-3);text-align:center;font-style:italic}
/* architecture */
#mtp-ax-explainer .ax-arch{margin:6px 24px 4px;border-top:1px solid var(--line);padding-top:18px}
#mtp-ax-explainer .ax-arch h3{font-size:12px;font-family:var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-2);margin-bottom:12px;font-weight:600}
#mtp-ax-explainer .ax-layers{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
#mtp-ax-explainer .ax-layer{cursor:pointer;border:1px solid var(--line);border-radius:12px;padding:14px;background:var(--tint);
transition:border-color .15s,background .15s;text-align:left}
#mtp-ax-explainer .ax-layer:hover{border-color:#C9CED6}
#mtp-ax-explainer .ax-layer[aria-expanded="true"]{border-color:var(--brand);background:#fff;box-shadow:0 0 0 3px rgba(22,87,224,.1)}
#mtp-ax-explainer .ax-layer .n{font-family:var(--mono);font-size:11px;color:var(--brand);font-weight:600}
#mtp-ax-explainer .ax-layer b{display:block;font-size:14px;margin:4px 0 0}
#mtp-ax-explainer .ax-layer .desc{font-size:12.5px;color:var(--ink-2);margin-top:8px;max-height:0;overflow:hidden;transition:max-height .25s;line-height:1.5}
#mtp-ax-explainer .ax-layer[aria-expanded="true"] .desc{max-height:120px}
/* フッター */
#mtp-ax-explainer .ax-foot{margin-top:16px;border-top:1px solid var(--line);padding:12px 24px;
display:flex;align-items:center;justify-content:space-between;gap:10px;background:var(--tint);flex-wrap:wrap}
#mtp-ax-explainer .ax-foot a{color:var(--brand);text-decoration:none;font-weight:600}
#mtp-ax-explainer .ax-foot a:hover{text-decoration:underline}
#mtp-ax-explainer .ax-brand{font-size:11.5px;color:var(--ink-3)}
#mtp-ax-explainer .ax-brand b{color:#0B8A00;font-weight:700}
@media (max-width:680px){
#mtp-ax-explainer .ax-grid{grid-template-columns:1fr}
#mtp-ax-explainer .ax-stats{grid-template-columns:repeat(3,1fr)}
#mtp-ax-explainer .ax-layers{grid-template-columns:1fr}
#mtp-ax-explainer .ax-previewwrap{position:static}
}
@media (prefers-reduced-motion:reduce){#mtp-ax-explainer *{transition:none!important}}
インタラクティブな解説
システムは一つ、デザインは多彩:Astryx が行動とブランドを分離する仕組み
以下のコンポーネント自体は不変です。変化するのはトークンだけです。テーマを選択し、スライダーを操作すれば、同じアクセシビリティ対応の React UI がコードを書き換えずにリスタイルされる様子を確認できます。
8 年間
本番環境で稼働中
Meta で 13,000 以上のアプリで使用
コンポーネント数 150+
テーマ 7 つ
MIT ライセンス
React 19+ StyleX
1 · テーマを選択
2 · トークンを調整
コーナー半径 10px
デンシティ(パディング)14px
ダークモード(標準搭載)
▸ このテーマが設定するトークンを表示
テーマ:ニュートラル
New
ミニマリストウォッチ
シンプルで洗練されたデザイン、日常使いに耐える耐久性。
$248
在庫あり
Apply
カートに入れる
マークアップも動作も同じ。スタイル変更は CSS カスタムプロパティのみで行っています。
仕組みの解説 · 3 つのレイヤー
01 ファウンデーション(基盤)
02 コンポーネント
03 パターン
実際のテーマを探索する →
インタラクティブな解説(表示されるカラーパレットは代表例です)· Marktechpost
(function(){
var root=document.getElementById('mtp-ax-explainer');
// Astryx が提供する7つのテーマを反映した代表的なトークンセット。
var THEMES={
neutral:{label:'neutral',primary:'#18181B',onp:'#ffffff',bg:'#ffffff',surface:'#F4F4F5',text:'#18181B',muted:'#6B7280',line:'#E4E4E7',radius:10,dot:'#18181B'},
butter:{label:'butter',primary:'#B7791F',onp:'#ffffff',bg:'#FFFEF6',surface:'#FEF7C7',text:'#422006',muted:'#8A6D2F',line:'#F3E4A8',radius:16,dot:'#EAB308'},
chocolate:{label:'chocolate',primary:'#7C4A2D',onp:'#ffffff',bg:'#FBF7F4',surface:'#EFE3D8',text:'#3B241A',muted:'#8A6B58',line:'#E3D2C4',radius:6,dot:'#7C4A2D'},
matcha:{label:'matcha',primary:'#3F7A3F',onp:'#ffffff',bg:'#F7FAF4',surface:'#E6F0DF',text:'#233620',muted:'#5C7A55',line:'#D4E4CB',radius:12,dot:'#4E9A4E'},
Astryx は、150 以上のアクセシブルなコンポーネント、7 つのテーマ、そして CLI を備えたエージェント対応の React デザインシステムとしてオープンソース化されました。
このデザインシステムのカラーパレットには、「stone」「gothic」「y2k」などの特徴的なテーマが含まれています。例えば「stone」は落ち着いたグレーを基調とし、「gothic」はモノクロームで洗練された印象を与え、「y2k」は鮮やかなパープルとピンクでレトロフューチャーな雰囲気を演出します。
システム内部では、これらのテーマが変数として定義され、ユーザーのデバイス設定や開発環境に応じて動的に切り替えることができます。また、角丸(radius)やパディング(pad)などのデザイントークンも個別に制御可能で、一貫性のある UI 体験を実現しています。
Astryx は、開発者が迅速かつ効率的に高品質な Web アプリケーションを構築できるよう支援する、包括的な設計基盤です。
// テーマ用チップの構築
var wrap=document.getElementById('axThemes');
order.forEach(function(key){
var t=THEMES[key];
var b=document.createElement('button');
b.className='ax-chip'; b.type='button';
b.setAttribute('aria-pressed', key===current?'true':'false');
b.innerHTML=''+t.label;
b.addEventListener('click',function(){ current=key; radius.value=t.radius; sync(); });
wrap.appendChild(b);
});
function darken(hex,amt){ // mix hex toward black
var c=hex.replace('#',''); var n=parseInt(c,16);
var r=(n>>16)&255,g=(n>>8)&255,bl=n&255;
r=Math.round(r*(1-amt)); g=Math.round(g*(1-amt)); bl=Math.round(bl*(1-amt));
return 'rgb('+r+','+g+','+bl+')';
}
function sync(){
var t=THEMES[current];
radiusV.textContent=radius.value; padV.textContent=pad.value;
var s=device.style;
var bg = dark? '#15171C' : t.bg;
var surface = dark? '#20242C' : t.surface;
var text = dark? '#F4F5F7' : t.text;
var muted = dark? '#A2AAB6' : t.muted;
var line = dark? '#2C313B' : t.line;
s.setProperty('--pv-bg',bg);
s.setProperty('--pv-surface',surface);
s.setProperty('--pv-text',text);
s.setProperty('--pv-muted',muted);
s.setProperty('--pv-line',line);
s.setProperty('--pv-primary',t.primary);
s.setProperty('--pv-onprimary',t.onp);
s.setProperty('--pv-radius',radius.value+'px');
s.setProperty('--pv-pad',pad.value+'px');
devtag.textContent='theme: '+t.label+(dark?' · dark':'');
// chips
Array.prototype.forEach.call(wrap.children,function(ch,i){
ch.setAttribute('aria-pressed', order[i]===current?'true':'false');
});
// tokens readout
tokensEl.innerHTML=
'--color-primary: '+t.primary+';\n'+
'--color-background: '+bg+';\n'+
'--color-surface: '+surface+';\n'+
'--color-text-primary: '+text+';\n'+
'--radius-container: '+radius.value+'px;\n'+
'--spacing-pad: '+pad.value+'px;\n'+
'--color-scheme: '+(dark?'dark':'light')+';';
}
radius.addEventListener('input',sync);
pad.addEventListener('input',sync);
var darkBtn=document.getElementById('axDark');
darkBtn.addEventListener('click',function(){ dark=!dark; darkBtn.setAttribute('aria-pressed',dark?'true':'false'); sync(); });
var tokBtn=document.getElementById('axTokBtn');
tokBtn.addEventListener('click',function(){
var open=tokensEl.classList.toggle('show');
tokBtn.setAttribute('aria-expanded',open?'true':'false');
tokBtn.textContent=(open?'▾':'▸')+' '+(open?'Hide the tokens this theme sets':'Show the tokens this theme sets');
})
// アコーディオンのアーキテクチャ
var layers=document.querySelectorAll('#axLayers .ax-layer');
layers.forEach(function(l){
l.querySelector('.desc').textContent=l.getAttribute('data-desc');
l.addEventListener('click',function(){
var open=l.getAttribute('aria-expanded')==='true';
layers.forEach(function(x){x.setAttribute('aria-expanded','false');});
l.setAttribute('aria-expanded', open?'false':'true');
});
});
// カウントアップ統計表示
var reduce=window.matchMedia&&window.matchMedia('(prefers-reduced-motion:reduce)').matches;
function countUp(el){
var target=+el.getAttribute('data-count'), suffix=el.getAttribute('data-suffix')||'';
if(reduce){ el.textContent=target.toLocaleString()+suffix; return; }
var start=null,dur=900;
function step(ts){ if(!start)start=ts; var p=Math.min((ts-start)/dur,1);
var val=Math.floor((1-Math.pow(1-p,3))*target);
el.textContent=val.toLocaleString()+suffix; if(p>=1){ counted=true;
document.querySelectorAll('#axStats b[data-count]').forEach(countUp); } }
window.addEventListener('scroll',maybeCount,{passive:true}); maybeCount();
sync();
// WordPress の自動リサイズ:このコンポーネントの高さ(documentElement の scrollHeight ではなく)をポストする
function postHeight(){
var h=root.offsetHeight+40;
if(window.parent){ window.parent.postMessage({type:'astryx-explainer-height',height:h},'*'); }
}
window.addEventListener('load',postHeight);
window.addEventListener('resize',postHeight);
new (window.ResizeObserver||function(){this.observe=function(){};})(postHeight).observe(root);
setTimeout(postHeight,300);
})();
エージェント向けに設計され、後付けされたものではない
Meta は Astryx を以下のように位置付けています
原文を表示
Meta has released Astryx, an open source design system that is fully customizable and built to be operated by both people and the AI agents working alongside them. It is available now in Beta. Astryx is not a new experiment. It grew inside Meta over the last eight years, where the company says it became its most-used and largest design system, shaped by the engineers, designers, and product teams who depend on it daily.
The system ships 150+ accessible components (the docs site now lists 160+), brand-level theming, dark mode, ready-to-ship templates, and a CLI as one cohesive package. It is built on React and StyleX. You import pre-built CSS and use typed React components. There is no build plugin to wire up and no styling library to adopt.
The trade-off Astryx is trying to remove
Most design systems force a choice. Adopt a large company’s system and your app tends to look like someone else’s product. Reach for copy-paste components instead and every project forks its own snippets, with no shared coherence, no upstream fixes, and accessibility quietly becoming your problem.
Astryx separates the two concerns. The system controls behavior, accessibility, and quality. Themes control how it looks. You customize at the token level (color, type, radius, motion) so the app becomes unmistakably yours without rewrites. A theme is simply a set of CSS custom property overrides, so a designer can retheme Astryx without forking or wrapping component source.
Its stated design principles are guidance over enforcement, strong documented conventions, one system for humans and AI, and earned by measurement — conventions are tested, not asserted.
Architecture: foundations, components, patterns
Astryx is organized in three layers. Foundations are the primitives for cohesive, accessible interfaces: typography, color, layout, and accessibility. Components are the 150+ reusable building blocks, all with full TypeScript support. Patterns are battle-tested solutions for common workflows: table pages, detail layouts, form wizards, navigation, and data-entry flows.
Two design decisions make it unusually open. Components are composed at any level rather than locked behind a closed top-level API, and swizzle can eject a component’s full source into your project when you need to own it. Styling is created with StyleX but stays invisible to consumers, so you can override with className using Tailwind, CSS modules, or plain CSS — whatever the project already uses. The explainer below shows how one set of components restyles across Astryx’s seven shipped themes when only the tokens change.
Astryx Explainer — Marktechpost
/* ===== Marktechpost · Astryx Interactive Explainer (LIGHT THEME) ===== */
#mtp-ax-explainer *{box-sizing:border-box;margin:0;padding:0}
#mtp-ax-explainer{
--ink:#16181D; --ink-2:#5A6270; --ink-3:#8A9099;
--line:#E6E8EC; --paper:#FFFFFF; --tint:#F6F7F9;
--brand:#1657E0; --brand-ink:#0B3AA8; --ok:#16A34A;
--mono:ui-monospace,"SF Mono","JetBrains Mono",Menlo,Consolas,monospace;
--sans:"Inter Tight",Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;
font-family:var(--sans); color:var(--ink); background:var(--paper);
line-height:1.5; -webkit-font-smoothing:antialiased;
border:1px solid var(--line); border-radius:16px; overflow:hidden;
max-width:900px; margin:0 auto;
}
#mtp-ax-explainer .ax-head{padding:22px 24px 18px;border-bottom:1px solid var(--line);background:
linear-gradient(180deg,#FBFCFE,#FFFFFF)}
#mtp-ax-explainer .ax-eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.14em;
text-transform:uppercase;color:var(--brand);font-weight:600;display:flex;align-items:center;gap:8px}
#mtp-ax-explainer .ax-eyebrow::before{content:"";width:22px;height:2px;background:var(--brand);border-radius:2px}
#mtp-ax-explainer h2.ax-title{font-size:22px;line-height:1.2;letter-spacing:-.02em;margin:10px 0 4px;font-weight:700}
#mtp-ax-explainer .ax-sub{color:var(--ink-2);font-size:14px;max-width:60ch}
/* stat band */
#mtp-ax-explainer .ax-stats{display:grid;grid-template-columns:repeat(6,1fr);gap:1px;background:var(--line);
border-bottom:1px solid var(--line)}
#mtp-ax-explainer .ax-stat{background:var(--paper);padding:14px 12px;text-align:center}
#mtp-ax-explainer .ax-stat b{display:block;font-size:20px;letter-spacing:-.02em;font-weight:700;color:var(--ink)}
#mtp-ax-explainer .ax-stat span{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.06em;
text-transform:uppercase;color:var(--ink-3);margin-top:3px}
#mtp-ax-explainer .ax-body{padding:22px 24px 8px}
#mtp-ax-explainer .ax-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:22px;align-items:start}
/* controls */
#mtp-ax-explainer .ax-panel h3{font-size:12px;font-family:var(--mono);letter-spacing:.08em;text-transform:uppercase;
color:var(--ink-2);margin-bottom:10px;font-weight:600}
#mtp-ax-explainer .ax-themes{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:18px}
#mtp-ax-explainer .ax-chip{cursor:pointer;border:1px solid var(--line);background:var(--paper);
border-radius:999px;padding:6px 12px 6px 8px;font-size:13px;font-weight:500;display:flex;align-items:center;gap:7px;
transition:border-color .15s,box-shadow .15s,transform .06s;color:var(--ink)}
#mtp-ax-explainer .ax-chip:hover{border-color:#C9CED6}
#mtp-ax-explainer .ax-chip .dot{width:14px;height:14px;border-radius:50%;box-shadow:inset 0 0 0 1px rgba(0,0,0,.08)}
#mtp-ax-explainer .ax-chip[aria-pressed="true"]{border-color:var(--brand);
box-shadow:0 0 0 3px rgba(22,87,224,.12)}
#mtp-ax-explainer .ax-chip:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
#mtp-ax-explainer .ax-sliders{display:grid;gap:14px;margin-bottom:16px}
#mtp-ax-explainer .ax-slider label{display:flex;justify-content:space-between;font-size:13px;color:var(--ink-2);margin-bottom:6px}
#mtp-ax-explainer .ax-slider label b{font-family:var(--mono);color:var(--ink);font-weight:600}
#mtp-ax-explainer input[type=range]{width:100%;accent-color:var(--brand);height:4px;cursor:pointer}
#mtp-ax-explainer .ax-toggle{display:inline-flex;align-items:center;gap:9px;font-size:13px;color:var(--ink-2);cursor:pointer;user-select:none}
#mtp-ax-explainer .ax-sw{width:38px;height:22px;border-radius:999px;background:#D5D9E0;position:relative;transition:background .18s}
#mtp-ax-explainer .ax-sw::after{content:"";position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;
background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.25);transition:transform .18s}
#mtp-ax-explainer .ax-toggle[aria-pressed="true"] .ax-sw{background:var(--brand)}
#mtp-ax-explainer .ax-toggle[aria-pressed="true"] .ax-sw::after{transform:translateX(16px)}
/* tokens readout */
#mtp-ax-explainer .ax-tokenbtn{margin-top:6px;font-family:var(--mono);font-size:12px;color:var(--brand);
background:none;border:none;cursor:pointer;padding:4px 0;text-decoration:underline;text-underline-offset:3px}
#mtp-ax-explainer .ax-tokens{margin-top:10px;background:#0E1116;border-radius:10px;padding:12px 14px;
font-family:var(--mono);font-size:12px;line-height:1.7;color:#C9D3E0;display:none;overflow-x:auto}
#mtp-ax-explainer .ax-tokens.show{display:block}
#mtp-ax-explainer .ax-tokens .k{color:#7FA6FF}
#mtp-ax-explainer .ax-tokens .v{color:#89E0B0}
/* live preview device */
#mtp-ax-explainer .ax-previewwrap{position:sticky;top:8px}
#mtp-ax-explainer .ax-device{border:1px solid var(--pv-line,#E6E8EC);border-radius:calc(var(--pv-radius,10px) + 6px);
background:var(--pv-bg,#fff);padding:16px;transition:background .25s,border-color .25s,border-radius .25s;
box-shadow:0 10px 30px -18px rgba(16,24,40,.35)}
#mtp-ax-explainer .ax-devbar{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}
#mtp-ax-explainer .ax-devdots{display:flex;gap:5px}
#mtp-ax-explainer .ax-devdots i{width:8px;height:8px;border-radius:50%;background:var(--pv-line,#E6E8EC);display:block}
#mtp-ax-explainer .ax-devtag{font-family:var(--mono);font-size:10px;color:var(--pv-muted,#8A9099);letter-spacing:.05em}
#mtp-ax-explainer .ax-card{background:var(--pv-surface,#F4F4F5);border:1px solid var(--pv-line,#E6E8EC);
border-radius:var(--pv-radius,10px);overflow:hidden;transition:all .25s}
#mtp-ax-explainer .ax-thumb{height:96px;background:
linear-gradient(135deg,var(--pv-primary,#18181B),color-mix(in srgb,var(--pv-primary,#18181B) 55%,#ffffff));
position:relative}
#mtp-ax-explainer .ax-badge{position:absolute;top:10px;left:10px;background:var(--pv-bg,#fff);color:var(--pv-primary,#18181B);
font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;padding:4px 8px;border-radius:999px}
#mtp-ax-explainer .ax-cardbody{padding:var(--pv-pad,14px)}
#mtp-ax-explainer .ax-cardbody h4{color:var(--pv-text,#18181B);font-size:15px;font-weight:700;margin-bottom:2px}
#mtp-ax-explainer .ax-cardbody p{color:var(--pv-muted,#6B7280);font-size:12.5px;margin-bottom:12px}
#mtp-ax-explainer .ax-row{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:12px}
#mtp-ax-explainer .ax-price{color:var(--pv-text,#18181B);font-weight:700;font-size:15px}
#mtp-ax-explainer .ax-input{flex:1;border:1px solid var(--pv-line,#E6E8EC);background:var(--pv-bg,#fff);
border-radius:calc(var(--pv-radius,10px) - 2px);padding:8px 10px;font-size:12.5px;color:var(--pv-text,#18181B);min-width:0}
#mtp-ax-explainer .ax-input::placeholder{color:var(--pv-muted,#9AA0AA)}
#mtp-ax-explainer .ax-btn{background:var(--pv-primary,#18181B);color:var(--pv-onprimary,#fff);border:none;
border-radius:calc(var(--pv-radius,10px) - 2px);padding:9px 14px;font-size:13px;font-weight:600;cursor:pointer;
font-family:var(--sans);white-space:nowrap;transition:filter .15s}
#mtp-ax-explainer .ax-btn:hover{filter:brightness(.94)}
#mtp-ax-explainer .ax-btn.ghost{background:transparent;color:var(--pv-primary,#18181B);
box-shadow:inset 0 0 0 1px var(--pv-primary,#18181B)}
#mtp-ax-explainer .ax-mini{display:flex;align-items:center;gap:8px;color:var(--pv-muted,#6B7280);font-size:12px}
#mtp-ax-explainer .ax-miniSw{width:32px;height:19px;border-radius:999px;background:var(--pv-primary,#18181B);position:relative;flex:none}
#mtp-ax-explainer .ax-miniSw::after{content:"";position:absolute;top:2px;right:2px;width:15px;height:15px;border-radius:50%;background:var(--pv-bg,#fff)}
#mtp-ax-explainer .ax-caption{margin-top:10px;font-size:11.5px;color:var(--ink-3);text-align:center;font-style:italic}
/* architecture */
#mtp-ax-explainer .ax-arch{margin:6px 24px 4px;border-top:1px solid var(--line);padding-top:18px}
#mtp-ax-explainer .ax-arch h3{font-size:12px;font-family:var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-2);margin-bottom:12px;font-weight:600}
#mtp-ax-explainer .ax-layers{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
#mtp-ax-explainer .ax-layer{cursor:pointer;border:1px solid var(--line);border-radius:12px;padding:14px;background:var(--tint);
transition:border-color .15s,background .15s;text-align:left}
#mtp-ax-explainer .ax-layer:hover{border-color:#C9CED6}
#mtp-ax-explainer .ax-layer[aria-expanded="true"]{border-color:var(--brand);background:#fff;box-shadow:0 0 0 3px rgba(22,87,224,.1)}
#mtp-ax-explainer .ax-layer .n{font-family:var(--mono);font-size:11px;color:var(--brand);font-weight:600}
#mtp-ax-explainer .ax-layer b{display:block;font-size:14px;margin:4px 0 0}
#mtp-ax-explainer .ax-layer .desc{font-size:12.5px;color:var(--ink-2);margin-top:8px;max-height:0;overflow:hidden;transition:max-height .25s;line-height:1.5}
#mtp-ax-explainer .ax-layer[aria-expanded="true"] .desc{max-height:120px}
/* footer */
#mtp-ax-explainer .ax-foot{margin-top:16px;border-top:1px solid var(--line);padding:12px 24px;
display:flex;align-items:center;justify-content:space-between;gap:10px;background:var(--tint);flex-wrap:wrap}
#mtp-ax-explainer .ax-foot a{color:var(--brand);text-decoration:none;font-weight:600}
#mtp-ax-explainer .ax-foot a:hover{text-decoration:underline}
#mtp-ax-explainer .ax-brand{font-size:11.5px;color:var(--ink-3)}
#mtp-ax-explainer .ax-brand b{color:#0B8A00;font-weight:700}
@media (max-width:680px){
#mtp-ax-explainer .ax-grid{grid-template-columns:1fr}
#mtp-ax-explainer .ax-stats{grid-template-columns:repeat(3,1fr)}
#mtp-ax-explainer .ax-layers{grid-template-columns:1fr}
#mtp-ax-explainer .ax-previewwrap{position:static}
}
@media (prefers-reduced-motion:reduce){#mtp-ax-explainer *{transition:none!important}}
Interactive explainer
One system, many skins: how Astryx splits behavior from brand
The components below never change. Only the tokens do. Pick a theme, drag the sliders, and watch the same accessible React UI restyle with no rewrites.
8 yrsIn production
13,000+Apps at Meta
150+Components
7Themes
MITLicense
React 19+ StyleX
1 · Choose a theme
2 · Tune the tokens
Corner radius 10px
Density (padding) 14px
Dark mode (built in)
▸ Show the tokens this theme sets
theme: neutral
New
Minimalist watch
Clean design, everyday durability.
$248
In stock
Apply
Add to cart
Same markup, same behavior — restyled only through CSS custom properties.
Under the hood · three layers
01Foundations
02Components
03Patterns
Explore the real themes →
Interactive explainer · palettes shown are representative · Marktechpost
(function(){
var root=document.getElementById('mtp-ax-explainer');
// Representative token sets that mirror Astryx's seven shipped themes.
var THEMES={
neutral:{label:'neutral',primary:'#18181B',onp:'#ffffff',bg:'#ffffff',surface:'#F4F4F5',text:'#18181B',muted:'#6B7280',line:'#E4E4E7',radius:10,dot:'#18181B'},
butter:{label:'butter',primary:'#B7791F',onp:'#ffffff',bg:'#FFFEF6',surface:'#FEF7C7',text:'#422006',muted:'#8A6D2F',line:'#F3E4A8',radius:16,dot:'#EAB308'},
chocolate:{label:'chocolate',primary:'#7C4A2D',onp:'#ffffff',bg:'#FBF7F4',surface:'#EFE3D8',text:'#3B241A',muted:'#8A6B58',line:'#E3D2C4',radius:6,dot:'#7C4A2D'},
matcha:{label:'matcha',primary:'#3F7A3F',onp:'#ffffff',bg:'#F7FAF4',surface:'#E6F0DF',text:'#233620',muted:'#5C7A55',line:'#D4E4CB',radius:12,dot:'#4E9A4E'},
stone:{label:'stone',primary:'#475569',onp:'#ffffff',bg:'#FAFAFB',surface:'#EEF0F3',text:'#1F2937',muted:'#64748B',line:'#E2E6EC',radius:8,dot:'#64748B'},
gothic:{label:'gothic',primary:'#111111',onp:'#ffffff',bg:'#ffffff',surface:'#ECECEC',text:'#111111',muted:'#555555',line:'#111111',radius:2,dot:'#111111'},
y2k:{label:'y2k',primary:'#C026D3',onp:'#ffffff',bg:'#FBF4FF',surface:'#FBE4FF',text:'#4A044E',muted:'#8B3FA0',line:'#F0C7FA',radius:22,dot:'#C026D3'}
};
var order=['neutral','butter','chocolate','matcha','stone','gothic','y2k'];
var current='neutral', dark=false;
var device=document.getElementById('axDevice');
var devtag=document.getElementById('axDevTag');
var tokensEl=document.getElementById('axTokens');
var radius=document.getElementById('axRadius'), pad=document.getElementById('axPad');
var radiusV=document.getElementById('axRadiusV'), padV=document.getElementById('axPadV');
// build theme chips
var wrap=document.getElementById('axThemes');
order.forEach(function(key){
var t=THEMES[key];
var b=document.createElement('button');
b.className='ax-chip'; b.type='button';
b.setAttribute('aria-pressed', key===current?'true':'false');
b.innerHTML=''+t.label;
b.addEventListener('click',function(){ current=key; radius.value=t.radius; sync(); });
wrap.appendChild(b);
});
function darken(hex,amt){ // mix hex toward black
var c=hex.replace('#',''); var n=parseInt(c,16);
var r=(n>>16)&255,g=(n>>8)&255,bl=n&255;
r=Math.round(r*(1-amt)); g=Math.round(g*(1-amt)); bl=Math.round(bl*(1-amt));
return 'rgb('+r+','+g+','+bl+')';
}
function sync(){
var t=THEMES[current];
radiusV.textContent=radius.value; padV.textContent=pad.value;
var s=device.style;
var bg = dark? '#15171C' : t.bg;
var surface = dark? '#20242C' : t.surface;
var text = dark? '#F4F5F7' : t.text;
var muted = dark? '#A2AAB6' : t.muted;
var line = dark? '#2C313B' : t.line;
s.setProperty('--pv-bg',bg);
s.setProperty('--pv-surface',surface);
s.setProperty('--pv-text',text);
s.setProperty('--pv-muted',muted);
s.setProperty('--pv-line',line);
s.setProperty('--pv-primary',t.primary);
s.setProperty('--pv-onprimary',t.onp);
s.setProperty('--pv-radius',radius.value+'px');
s.setProperty('--pv-pad',pad.value+'px');
devtag.textContent='theme: '+t.label+(dark?' · dark':'');
// chips
Array.prototype.forEach.call(wrap.children,function(ch,i){
ch.setAttribute('aria-pressed', order[i]===current?'true':'false');
});
// tokens readout
tokensEl.innerHTML=
'--color-primary: '+t.primary+';\n'+
'--color-background: '+bg+';\n'+
'--color-surface: '+surface+';\n'+
'--color-text-primary: '+text+';\n'+
'--radius-container: '+radius.value+'px;\n'+
'--spacing-pad: '+pad.value+'px;\n'+
'--color-scheme: '+(dark?'dark':'light')+';';
}
radius.addEventListener('input',sync);
pad.addEventListener('input',sync);
var darkBtn=document.getElementById('axDark');
darkBtn.addEventListener('click',function(){ dark=!dark; darkBtn.setAttribute('aria-pressed',dark?'true':'false'); sync(); });
var tokBtn=document.getElementById('axTokBtn');
tokBtn.addEventListener('click',function(){
var open=tokensEl.classList.toggle('show');
tokBtn.setAttribute('aria-expanded',open?'true':'false');
tokBtn.textContent=(open?'▾':'▸')+' '+(open?'Hide the tokens this theme sets':'Show the tokens this theme sets');
});
// architecture accordion
var layers=document.querySelectorAll('#axLayers .ax-layer');
layers.forEach(function(l){
l.querySelector('.desc').textContent=l.getAttribute('data-desc');
l.addEventListener('click',function(){
var open=l.getAttribute('aria-expanded')==='true';
layers.forEach(function(x){x.setAttribute('aria-expanded','false');});
l.setAttribute('aria-expanded', open?'false':'true');
});
});
// count-up stats
var reduce=window.matchMedia&&window.matchMedia('(prefers-reduced-motion:reduce)').matches;
function countUp(el){
var target=+el.getAttribute('data-count'), suffix=el.getAttribute('data-suffix')||'';
if(reduce){ el.textContent=target.toLocaleString()+suffix; return; }
var start=null,dur=900;
function step(ts){ if(!start)start=ts; var p=Math.min((ts-start)/dur,1);
var val=Math.floor((1-Math.pow(1-p,3))*target);
el.textContent=val.toLocaleString()+suffix; if(p0){ counted=true;
document.querySelectorAll('#axStats b[data-count]').forEach(countUp); } }
window.addEventListener('scroll',maybeCount,{passive:true}); maybeCount();
sync();
// WordPress auto-resize: post this component's own height (never scrollHeight of documentElement)
function postHeight(){
var h=root.offsetHeight+40;
if(window.parent){ window.parent.postMessage({type:'astryx-explainer-height',height:h},'*'); }
}
window.addEventListener('load',postHeight);
window.addEventListener('resize',postHeight);
new (window.ResizeObserver||function(){this.observe=function(){};})(postHeight).observe(root);
setTimeout(postHeight,300);
})();
Built for agents, not retrofitted for them
Meta frames Astryx as
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み