12k
All articles

Meta のデザインシステム「Astryx」を初めて触ってみる

MetaのオープンソースデザインシステムAstryxは、150以上のReactコンポーネント、テーマ、CLI設定、カスタマイズ段階、shadcn/uiとBase UIとの比較を解説します。

OpenReplay Team
OpenReplay Team
Meta のデザインシステム「Astryx」を初めて触ってみる

Astryx は、Meta が社内で育ててきたデザインシステムをオープンソースとして再構築したものです。2026年6月18日に Astryx のブログで発表され、MIT ライセンスのパブリックベータとして公開されました。150 を超えるアクセシブルな React コンポーネント、7 種類の既製テーマ、テンプレート、CLI を同梱し、React 19 以降と StyleX の上に構築されています。

MUI でプロダクトを出荷した経験があれば、トレードオフの一方の姿をご存知でしょう。コンポーネントは動く。しかしその後、ボタンを「他人のボタン」に見えなくするために、テーマオブジェクトと格闘してスプリントを 1 本使い切ることになります。shadcn/ui のソースを自分たちで抱えている人は、もう一方の姿を知っています。40 個のコンポーネントファイルが自分のリポジトリにあり、完全に自分のもので、フォーカス管理の修正を取り込むべき upstream は存在しません。

Meta の主張は、Astryx がその両者の中間に位置するというものです。機能リストは簡単に見つかりますが、導入コストを実際に左右するのは「5 段階のカスタマイズの階段」であり、そのうちどの段にチームが住み着くことになるかです。本記事では、Astryx とは何か、どうインストールして利用するのか、テーマはどう機能するのか、その階段の各段が何を代償として要求するのか、そして shadcn/ui や Base UI と並べたときにどこに位置するのかを扱います。

要点

  • Astryx は React 19 以降を必要とし、@astryxdesign/core は react、react-dom、@stylexjs/stylex を peer dependencies として指定しています。
  • Astryx は 2 つの配布経路を用意しています。プリコンパイル済みのスタイルシートをインポートするか、TypeScript と StyleX のソースからビルドして、インポートしたコンポーネントの分だけバンドラーが CSS を出力するようにするかです。
  • カスタマイズは 5 段階で段階的に上がっていきます。共有のアップグレード経路から外れるのは最後の段、つまりコンポーネントのソースを自分のリポジトリに swizzle した場合だけです。
  • コンポーネントは型付きの xstyle prop と素の className の両方を受け取ります。プリコンパイル経路ならビルドに何も追加しません。バンドラープラグインも PostCSS も Babel 設定も不要です。
  • Astryx は依然として 0.x リリースのパブリックベータであり、安定版のラインは存在しません。そのため API の変動は現実的なコストです。

Astryx とは何か

Astryx は、周囲にシステム全体が組み込まれたコンポーネントライブラリです。型付きの React コンポーネントがプリコンパイル済み CSS と並んで提供され、さらにブランドレベルのテーマ設定、ダークモード、ページテンプレート、CLI が、ひとまとまりのパッケージ群として配布されます。Meta の技術解説記事では、社内で 8 年にわたって育ち、13,000 を超えるプロダクトに到達し、更新のおよそ半分を社内のビルダーコミュニティから取り込んできたシステムのオープンソース再構築版として紹介されています。スタイルは StyleX で記述されています。StyleX は Meta のコンパイラで、スタイルオブジェクトをビルド時にアトミックで衝突しない CSS へ変換します。CSS-in-JS への反対理由がランタイムコストである人にとっては重要な点です。ブラウザ上でスタイルエンジンが動くことはありません。

このプロジェクトでの作業の大半は CLI を通じて行われます。人間にとっても機械にとっても同様です。コンポーネントのドキュメント、デザイントークン、ページテンプレート、テーマ関連ツール、アップグレード用 codemod は、すべてここから出てきます。ターミナルから呼び出す、型付き JSON 出力を読む、関数としてインポートする、いずれの方法でも構いませんし、エージェントやビルドツールも同じ API を経由します。プロジェクト自身がこれを「AI-fluent」でエージェント対応だと位置づけているのは、あくまでポジショニングであって計測結果ではありません。Meta が説明している評価ハーネスについては、どちらの発表記事にも結果が公開されていません。

実際にはどう Astryx を利用するのか

React 19 が下限です。@astryxdesign/core はreact と react-dom を 19.0.0 以上の peer dependencies として列挙しています。これが最初の関門です。2 番目は成熟度です。@astryxdesign/core は npm 上で 0.x ラインとして公開されており、@astryxdesign/vega と @astryxdesign/charts は @canary dist-tag でしか実際のビルドを配布しておらず、latest タグは依然としてプレースホルダーのリリースを指しています。

core パッケージ、テーマパッケージ、StyleX の peer をインストールし、CLI は dev dependency として入れます。

npm install @astryxdesign/core @astryxdesign/theme-neutral @stylexjs/stylex
npm install -D @astryxdesign/cli
npx @astryxdesign/cli init

init ステップは、Astryx のコンポーネントインデックスを AGENTS.md または CLAUDE.md に書き込みます。リポジトリにエージェントが関与しないならスキップして構いません。シンプルな経路では、この後スタイルシートを 3 つ順番にインポートし、アプリをテーマプロバイダーでラップします。

@import '@astryxdesign/core/reset.css';
@import '@astryxdesign/core/astryx.css';
@import '@astryxdesign/theme-neutral/theme.css';

リポジトリ自身の説明によれば、これでセットアップは完了です。3 つのインポートとプロバイダーだけで、ビルドツールチェーンへの変更はありません。高度な経路では、@astryxdesign/build を使って TypeScript と StyleX のソースからビルドします。このパッケージには Babel、PostCSS、Vite のプラグインが含まれており、実際にインポートしたコンポーネントの分だけバンドラーがスタイルを出力します。Meta は自社のリファレンスアプリで、この経路によりスタイルシート全体の約 3 分の 1 になると示していますが、これは彼ら自身のコードでの計測であって一般的な法則ではありません。各コンポーネントはパッケージルートではなく、それぞれのサブパスから提供されます。

テーマ設定: 振る舞いはシステムに、外観はトークンに

Astryx は責務をきれいに二分しています。振る舞いとアクセシビリティはライブラリ側に、外観はトークンレイヤーに置かれます。したがってテーマ設定は色、タイポグラフィ、角丸、スペーシング、モーションを保持し、1 つの値を編集すれば、それを参照するすべてのコンポーネントのスタイルが、誰もコンポーネントコードを開くことなく変わります。ライトとダークの値は 2 つの並行ファイルに分かれるのではなく、同じテーマの中に並んで置かれ、テーマはランタイムに切り替えることも、静的なスタイルシートにコンパイルすることもできます。テーマは CSS 変数の域を超えます。個々のコンポーネントやコンポーネントのパーツをオーバーライドし、独自のバリアントを追加することもできます。

既製テーマが 7 つ同梱されており、ゼロからではなくそのいずれかから始めます。theme list は、インストール済みインテグレーション由来のテーマを含め、利用可能なものを表示し、theme add <slug> は選んだテーマを編集可能なソースとしてプロジェクトに配置します。設計上の賭けを一行で言えばこうです。デザイナーが設定ファイルを所有し、見た目を変えるためにコンポーネントをフォークしたりラップしたりする必要が誰にもない、ということです。

段階的なカスタマイズ経路

Astryx のカスタマイズは 5 段階で上がっていきます。出荷されたままコンポーネントを使う、テーマトークンを調整する、クラス名を付与する、独自の CSS を重ねる、そして最後にコンポーネントのソースをリポジトリへ swizzle する、という順序です。上の段に行くほど制御は増え、所有コストも増えます。最初の 4 段は共有のアップグレード経路に留まりますが、5 段目はそのコンポーネントを恒久的にその経路から外します。

段変更するもの代償
そのまま使うなしなし。アップグレードは無料
テーマトークン色、書体、角丸、スペーシング、モーションチームで保守する設定ファイル
クラス名インスタンスごとの外観カスケードレイヤーの規律
カスタム CSSレイヤー順序が許す範囲のすべてアップグレードで壊れうるセレクタ
Swizzleコンポーネント自体恒久的なフルメンテナンス

Swizzle は一方通行の扉です。プライベートな state、DOM 構造、到達できないイベントリスナーなど、公開 API では単に露出されていない内部があり、それらに触れる唯一の手段はソースの eject です。その時点から、あなたが保守するのはライブラリではなくそのコンポーネントになります。CLI は astryx swizzle Button と astryx upgrade --apply でコンポーネントのソースを eject し、バージョン用 codemod を実行します。

npx @astryxdesign/cli swizzle Button

単発実行にはスコープ付きの形式を使ってください。@astryxdesign/cli が依存関係に入るまでは、npm は素の astryx を無関係なパッケージに解決します。Astryx を採用する前の実務的な一手は、最も難しいコンポーネント 2〜3 個を 5 段目に照らして確認することです。必要なカスタマイズが内部への到達を要求するなら、初日からそのソースを所有するコストを見込んでおきましょう。

スタイリングの相互運用: xstyle、className、Tailwind

Astryx のコンポーネントは、StyleX オーバーライド用の型付き xstyle prop と素の className の両方を受け取るため、Tailwind、CSS Modules、素のスタイルシートと共存できます。同じコンポーネントを 3 通りで書くとこうなります。

import * as stylex from '@stylexjs/stylex';
import {Button} from '@astryxdesign/core/Button';

const styles = stylex.create({
  save: {alignSelf: 'flex-end', marginBlockStart: 24},
});

// 1. As shipped
<Button label="Save" variant="primary" />;

// 2. Typed StyleX override, compiled at build time
<Button label="Save" variant="primary" xstyle={styles.save} />;

// 3. Plain className, no compiler involved
<Button label="Save" variant="primary" className="ml-auto mt-6" />;

プリコンパイル経路では、3 番目の選択肢に追加のツールチェーンは不要です。StyleX は Astryx がスタイルを記述するための手段であって、あなたが設定しなければならないものではありません。ただし 1 つ条件があります。Astryx はスタイルシートをカスケードレイヤーに読み込みます。リセットは @layer reset、コンポーネントスタイルは @layer astryx-base です。そしてレイヤーは詳細度に従いません。レイヤー外に置かれたもの、あるいは後から宣言されたレイヤーに置かれたものは、いずれにせよ勝ちます。したがって、既にグローバル CSS や古いリセット、Tailwind を抱えているプロジェクトは、自分でレイヤー順序を設定し、すべてのスタイルシートを意図的にレイヤーへ入れる必要があります。

Astryx と shadcn/ui、Base UI はどう違うのか

Meta はローンチ記事で挙げた 2 つの帰結に対して Astryx を位置づけています。大企業のデザインシステムを採用すればそのブランドまで受け継ぐことになるし、コピー&ペーストしたコンポーネントを組み上げれば自由は得られるが、共有された一貫性、upstream の修正、アップグレード経路を手放し、アクセシビリティはデフォルトで自チームの負担になる、という主張です。これは Meta による自社製品の弁護であり、代替となる各プロジェクトが自らについて何を述べているかと照らし合わせる価値があります。shadcn/ui は自身をその逆向きに説明しています。インストールするライブラリではなく、自分のライブラリを構築するための手段であり、直接編集できるコンポーネントコードを手渡すものだ、と。コードを所有することは副作用ではなく機能そのものです。この点はチームが shadcn/ui に移行する理由についての記事でより詳しく扱っています。Base UI は独自の CSS を持たないヘッドレスな React コンポーネントとフックを提供するため、見た目は完全にあなたの判断次第です。

評決ではなく制約として読んでください。Base UI はアクセシブルな振る舞いを与え、意見は持ちません。shadcn/ui はソースと、それに伴う保守を与えます。そして Astryx はテーマ付きのシステムを与えつつ、コンポーネント単位で eject する余地を残します。Astryx の 5 段目は、別の道筋で shadcn/ui の立場に到達します。一度に 1 コンポーネントずつ、しかもあなたが選んだときだけです。

留意点は単純です。安定版ラインのない 0.x のパブリックベータであり、React 19 という関門があり、単一ベンダーのプロジェクトです。ローンチ時の議論ではガバナンスと長期保守に関する疑問が挙がりましたが、公開情報でそれを解決するものはありません。ベータ期の変動は仮定の話ではありません。0.6.0 リリースは useStepperContext を直接呼んでいるコードを壊します。このフックからコンパクトレイアウト関連のフィールドを取り除き、StepperContextValue を遷移履歴とステップ登録に絞り込んでいます。一方で、コミュニティページには公式 Discord と、毎週トリアージされる GitHub issues が記載されています。

今 Astryx を試すべきなのは誰で、待つべきなのは誰か

React 19 でグリーンフィールドの社内ツールやダッシュボードを始めようとしていて、アクセシブルなコンポーネントを自分で設計せずに欲しく、CSS のプルリクエストをレビューするよりトークンを所有したいデザイナーがいるなら、今試してください。React 19 未満なら、あるいは 0.x のマイナーリリースが context の形を変えただけでリリース 1 本を失うような一般公開プロダクトを保守しているなら、あるいは単一ベンダーのガバナンスがまだ答えを出せない調達上の論点なら、待ちましょう。有用な中間策は、既存アプリのルート 1 つで試すことです。プリコンパイル済みスタイルシート、明示的な @layer 順序、そして本来なら自分たちで書いていたであろうコンポーネントで構成した画面を 1 つ作るのです。

評価すべきはコンポーネント数ではありません。あなたのデザイン要件がカスタマイズの階段のどの段へ追い込むか、です。1 年後に支払っているのはそれだからです。プロダクトが妥協できないコンポーネントを 2 つ選び、それぞれに対して npx @astryxdesign/cli component <Name> を実行し、ソースの eject に至る前にトークンと className で目的に届くかどうかを確かめてください。

FAQ

Astryx と StyleX の違いは何ですか?

StyleX は Meta のビルド時 CSS-in-JS コンパイラで、スタイルオブジェクトをアトミックで衝突しない CSS に変換します。Astryx は、そのスタイルが StyleX で記述された React コンポーネントからなるデザインシステムです。Astryx は @stylexjs/stylex を peer dependency としてインストールしますが、プリコンパイル済みスタイルシートを利用する場合はビルドプラグインも PostCSS も Babel 設定も不要です。StyleX のプラグインを @astryxdesign/build から取り込むのは、ソースからビルドする場合だけです。

Astryx は Next.js、Vite、素の CDN 構成で動きますか?

はい。@astryxdesign/core の README には Next.js、Tailwind、Vite、CDN のセットアップが記載されています。プリコンパイル経路では、リセット、コンポーネントスタイルシート、テーマスタイルシートをインポートし、アプリをテーマプロバイダーでラップするだけで、バンドラープラグインは関与しません。代わりに TypeScript と StyleX のソースからビルドする場合は、@astryxdesign/build に同梱された Babel、PostCSS、Vite のいずれかのプラグインが必要です。

ライブラリを使うのに Astryx CLI は必要ですか?

いいえ。コンポーネントとプリコンパイル済み CSS は、インストール済みのパッケージだけで動作し、CLI は dev dependency です。CLI が必要になるのは theme list と theme add、完全なコンポーネントドキュメント、テンプレート、アップグレード用 codemod、そして swizzle のときです。astryx init を実行すると Astryx のコンポーネントインデックスが AGENTS.md または CLAUDE.md に書き込まれますが、これはリポジトリで AI エージェントが作業する場合にのみ意味があります。

Astryx のチャートコンポーネントは本番利用に耐えますか?

いいえ。Vega ラッパーの @astryxdesign/vega と、d3 ベースのチャートライブラリ @astryxdesign/charts は、canary dist-tag でしか実際のビルドを npm に公開していません。latest タグはプレースホルダーのリリースを指しており、npm 自身がインストールしないよう警告します。新しいコンポーネントが core に昇格する前に着地する実験的パッケージ @astryxdesign/lab も同じ方式で公開されています。したがってチャート機能は、すでにベータである 0.x の core パッケージよりさらに後方にあり、独自のフォールバック計画が必要です。

Digital experience platform

Truly understand users experience

See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.