統合UX基盤というチームでエンジニアをしているtakumiです。freee Developers Advent Calendar 2024の20日目は、現在社内向けに開発を進めている新しいUIライブラリ「標準UI」について、その特徴や開発過程を紹介していきます。
デザインシステムの浸透と新たな課題
freeeでは2018年からデザインシステム「vibes」を開発・運用してきました。最近ではOSSとして公開し、アクセシビリティをはじめとするフロントエンド開発のノウハウを広く共有できるようになりました。以前の記事「デザインシステム "Vibes" の育てかた」でも詳しく解説していますが、vibesの導入により、ボタンやフォームといった個々のUIコンポーネントのデザインは標準化され、一定の成果を上げることができました。
しかし、アプリケーションの規模が拡大し開発チームが増えていく中で、新たな課題が見えてきました。個々のコンポーネントは揃っていても、その組み合わせ方は各開発チームの裁量に委ねられていました。その結果、想定外の使い方が発生したり、同じような目的の機能でもアプリケーションによってUIが異なる状況が生まれていました。
この状況はユーザーに学習コストの増大や混乱を招くだけでなく、開発チームにとっても大きな課題となりました。実装の面だけでなく、UIに関する議論や意思決定においても、各チームで同じような検討を繰り返す必要がありました。
こうした問題を解決するため、専任のチームを発足し、2つの取り組みを開始しました。1つ目は、freeeとして提供すべき業務アプリ像を改めて定義し、ユーザーの要求を実現するための情報設計の指針を言語化したデザインプリンシプルの策定です。2つ目は、誰でも1そのプリンシプルに準拠したUIを実装できる高機能なUIライブラリの開発です。このプロジェクトおよびライブラリは、極力コンテキストを廃して入社初日の人でも理解できるようにという意思を込めて、「標準UI」(パッケージとしては standard-ui
)という名称にしました。
標準UIの構成要素
画面パターンレベルのデザインシステム
標準UIは、既存のデザインシステムであるvibesをdependenciesに持ち、そのコンポーネントを内部的に使用する形で設計されています。
Atomic Designの考え方に基づくと、vibesは主にLv1(Atoms)とLv2(Molecules)という小さな粒度のコンポーネントを提供します。具体的には、ボタンやテキストフィールドといった最小単位のUI部品、またそれらを組み合わせた検索フォームやページネーションといった中規模の機能ブロックが該当します。
一方、標準UIはvibesのコンポーネントを組み合わせてLv3(Organisms)やLv4(Templates)という、より大きな単位のコンポーネントを提供します。開発の最初のフェーズとして、業務システムにおいて最も基本的かつ重要となる以下のようなパターンにフォーカスしました。
- レコードの一覧をテーブルなどの形式で確認する画面
- 個別のレコードの詳細を閲覧する画面
- レコードを新規作成/編集する画面
標準UIでは、これらの画面を一つのコンポーネントを配置するだけで作成できるようにしています。これにより開発者は個々のUIコンポーネントの組み合わせ方を考える必要がなく、ビジネスロジックの実装に注力できる状態を目指しました。
内製のライブラリならではの強みとして、実際のユースケースやドメインに最適化されたUIを提供できます。例えば一括処理の機能では、サーバーサイドの特性(同期/非同期処理、実行中の操作制御、失敗時の挙動)に応じたUIのバリエーションを用意しています。
ページネーションについても、データ量やユースケースに応じて様々な実装パターンを提供します。全件数の表示有無、オフセット式やカーソル式の選択、レコード数の上限値の考慮など、freeeのプロダクトで実際に必要となる要件をカバーしています。さらに、会計における仕訳を表現するためのテーブルなど、ドメイン固有のUIコンポーネントも提供しています。
フロントエンドアプリケーションのロジック
画面パターンレベルのコンポーネントになると、実際のユースケースにおいては多くのロジックが必要になり、またロジックの実装方法がユーザー体験に違いをもたらす場合もあります。デザインシステムという枠組みからは逸脱しますが、こうしたロジックも標準化すべき対象として内包する方向性にしました。
状態管理
- URLクエリと連動した検索フィルタの状態管理
- 一括処理のための項目選択機能
- ダイアログ操作の状態管理
API連携
- OpenAPIスキーマを元にしたAPI通信
- エラーハンドリング
- リソースの取得と更新処理
ドメイン固有の機能
- 取引先、部門、従業員などのマスタ情報を扱うコンポーネント
- 郵便番号から住所を補完するモジュール
- その他freeeのアプリケーションで共通して使用される機能
こうしたロジックを標準化して提供することで、統一的なユーザー体験を担保しつつ、開発者は車輪の再発明を防ぎ、それぞれのプロダクト固有の価値提供に注力できる状態を目指しています。
開発支援エコシステム
標準UIの導入をより円滑にするため、開発支援ツールも別パッケージとして提供しています。サーバーサイドとの連携を効率化するOpenAPI定義からのprops生成ジェネレーターや、E2Eテストの記述を容易にするPlaywright用のPOM(Page Object Model)などが含まれます。これらのツールにより、開発からテストまでのワークフローをスムーズに進められるよう設計しています。
今後の展望
現在の課題と対応
開発当初、ロジックを含んだTemplateレベルのコンポーネントを提供し、一つのコンポーネントで画面全体を表現する形式を採用していました。この方式はゼロから画面を作る場合においては一定の効果を発揮しましたが、複数のアプリケーションへの導入を進めるなかでいくつかの課題が見えてきました。
- コンポーネントのpropsが巨大になり、認知負荷が大きくなる
- 実装方法を調べるためのコストが大きい
- 実行時や型チェック時のエラーが発生した際のトラッキングが難しい
- 既存ロジックからの移行コストや互換性の担保が課題となる
これらの問題は、特に既存の画面を標準UIを使用して置き換える際に顕著でした。
そこで全体的な設計の見直しを行い、コンポーネントの粒度を細かくする方向で改善を進めました。具体的には、Templateレベル(Lv4)のコンポーネントをOrganism(Lv3)に分解し、ヘッダーのみ、フィルタ領域のみといった具合に段階的な導入ができるようにしました。これにより、propsが小さくなることで認知負荷と調査コストが軽減され、各コンポーネントの責務の範囲もより明確になりました。さらに、内包されるロジックはオプトアウト可能にすることで、既存ロジックを流用できるような構造へと変更しています。
粒度を細かくすると、当初の課題であった逸脱したUIが生まれてしまうというリスクも生じますが、一旦は導入のしやすさを重視したインターフェースに変更した上で、そうした部分はガイドラインの整備やレビュープロセスで担保する方針に転換しました。後述する将来的なビジョンを踏まえると、1コンポーネント1画面というスタイルに回帰する可能性もあります。
将来のビジョン
標準UIは今後改善を続けながらより多くのUIパターンに対応できるように拡張していく予定です。そして提供するパーツが充実し社内での利用が広がったその先には、以下のような発展の可能性を見据えています。
WYSIWYGなエディタの開発
GUI上で標準UIを使用した画面を組み立てることができるツールの開発を検討しています。これが実現すれば、エンジニア以外のメンバーでもコーディングなしで画面開発が可能になります。技術的な実現可能性は十分にありますが、標準UIの進化に合わせた継続的なメンテナンスコストが発生するため、開発着手のタイミングは慎重に見極める必要があります。
Server-Driven UIの採用
Server-Driven UIはAirbnbなどが採用している、UIの構造をバックエンドからAPIレスポンスとして返却する設計手法です。これによりバックエンド主体でUIの更新を行うことが可能になります。
A Deep Dive into Airbnb's Server-Driven UI System | by Ryan Brooks | The Airbnb Tech Blog | Medium
単一のコンポーネントで画面を表現する標準UIであればそのままServer-Driven UIのクライアントとしても機能することが期待されるため、こうした設計とも親和性が高いと考えています。
AIによる自動生成
AIによるコード生成において、標準UIを使用したコードを出力できれば、UIの一貫性を保ちながら生産性を向上させることができます。実用に関してはまだ研究中の部分も多いですが、普段の開発においてはpropsのリファレンス的な列挙など、AIにとって解釈しやすい形式でのドキュメント整備を進めています。
終わりに
このプロジェクトで用いている個々の技術に目新しさはありませんが、それらを組み合わせて標準のUIを定義し、組織全体に浸透させていく過程には多くの工夫が必要でした。
標準UIは現在も発展途上のプロジェクトですが、freeeのプロダクト開発の効率化とUIの統一に大きく貢献できる可能性を秘めています。今後も実際の開発現場からのフィードバックを得ながら、より使いやすく強力な開発基盤として進化させていきたいと考えています。
- freeeではWebアプリケーションにおいてサーバーサイドエンジニア・フロントエンドエンジニアといった区分を設けていないため、誰でもフロントエンドに触れる機会があります↩