2025年3月6日、アウェアファイのWebアプリを式年遷宮 リプレースを実施する機会があり、リリースに至りました。

アウェアファイ - AIメンタルパートナー
アウェアファイは、科学的に根拠のある心理学の理論とAI技術をかけ合わせ、心の健康と成長をサポートするアプリです。これまで70万人以上の方をサポートしてきました。AIキャラクター「ファイさん」との対話機能や、自分の心のコンディションを分析する機能、マインドフルネス瞑想に取り組める音声ガイドや課題別の学習コースなど、メンタルヘルスケアに必要なコンテンツが300種以上揃っています。

現在、アウェアファイのコア機能は iOS/Android のモバイルアプリとして提供しています。Webアプリについては限定的な機能を提供しているにとどまっているのですが、今後Webアプリを発展させていくことを事業上の優先事項の1つとしています。そのため、事業成長に求められる速度で機能の開発・改善が行えるような基盤をつくる、ということをミッションに掲げ、プロジェクトを進行していました。

今回、ゼロベースでWebアプリを開発するにあたり技術スタックの選定を行いました。個人的にも学びが深かったので、本稿で採用した技術スタックに焦点を当てて知見の共有を行いたいと思います。2025年にWebアプリを立ち上げるなら、という観点で参考にしていただけると幸いです。

採用した技術スタック

今回採用した技術スタックは次のとおりです。

続いて、採用した技術スタックのうちいくつかの紹介および補足をしたいと思います。

TanStack Start

TanStack Start は、TanStack Router をベースとした、CSR だけではなく SSR にも対応した React のメタフレームワークです。

TanStack Start
Full-document SSR, Streaming, Server Functions, bundling and more, powered by TanStack Router, Nitro, Vite and ready to deploy to your favorite hosting provider.
TanStack Router
A powerful React router for client-side and full-stack react applications. Fully type-safe APIs, first-class search-params for managing state in the URL and seamless integration with the existing React ecosystem.

TanStack Start は2025年3月時点でまだ β の状態ですが、機能の多くの部分が TanStack Router であることから(TanStack Router は v1 に達しています)、また全体的に TanStack シリーズへの信頼感もあることから問題視せず採用に至っています。

比較した結果採用しなかったメタフレームワークは以下のとおりです。

  • Next.js : チーム規模や実現したいことに対してライブラリが巨大であることと、リプレース前のプロジェクトが Next.js を採用していていて今回の判断に至ったという経緯もあり(前提としてフレームワーク自体が悪いということではないのですが)、今回は採用しませんでした。
  • React Router v7 (Remix) : 有力候補でしたが、最終的に React Router と Remix 統合の先にどのようになっていくか不明瞭であったため採用を見送りました。

(なお、本稿をつうじてですが、不採用となったのはチームの個別事由や、最終的にはひとつの意志決定の結果に過ぎず、読者に対して不採用を推奨するものではありませんので、その点をくれぐれもご理解ください)

shadcn + Tailwind v4

shadcn(シャドシーエヌ)は Tailwind ベースの UIコンポーネントライブラリで、ここ数年のトレンドでもあるコピー&ペーストでコンポーネントを追加する方式で提供されているものです。shadcn 専用のコマンドラインツールもあり、npx shadcn add button のようなコマンドでプロジェクトにUIコンポーネントを追加できます。

ちなみに、TanStack Start を知ったのは shadcn のチュートリアルに TanStack Start が含まれていたためでした。

TanStack Start
Install and configure shadcn/ui for TanStack Start.

比較した結果採用しなかったUIコンポーネントライブラリについて、じっさい非常に多くのライブラリを検討したためすべてを掲載することが難しいのですが、そのうちで特に興味深いと感じたプロジェクトのいくつかを掲載します。

Preline UI - Tailwind CSS components library
Preline UI is an open-source Tailwind CSS components library for any needs. Comes with UI examples & blocks, templates, plugins, Figma design system and more.

Preline は Taliwind CSS ベースのコンポーネントライブラリです。有料の Pro 版が用意され、Figma ファイルも提供されていることからチームで導入しやすい印象を持ちました。

HeroUI (Previously NextUI) - Beautiful, fast and modern React UI Library
Beautiful, fast and modern React UI Library

HeroUI は、NextUI として開発されていたものです。その名前のとおり NextUI 時代は Next.js を前提にしていたプロジェクトが、Next.js に縛られず React のコンポーネントライブラリとして開発していくことになったという変遷を辿っているようです。

Origin UI - Beautiful UI components built with Tailwind CSS and React
An extensive collection of copy-and-paste components for quickly building app UIs. Free, open-source, and ready to drop into your projects.

Origin UIも、Tailwind CSS のコピー&ペースト方式をとるコンポーネントライブラリのひとつです。コンポーネントのバリエーションが多く、多くのユースケースをカバーできるであろう点が魅力です。いっぽう、数が多いことの裏返しか、全体的な統制には難があるようにも見受けられ、どういった基準でどのコンポーネントを採用するかといったガイドラインが必要になるかもしれません。

shadcn + Tailwind v4 の活用事例やデザインシステム構築に関する情報は別途共有する予定もあるため、公開のおりにはそちらを参照いただきたいと思います。

TanStack Query

TanStack シリーズのなかでも人気のあるライブラリが TanStack Query(旧 React Query)です。

TanStack Query
Powerful asynchronous state management, server-state utilities and data fetching. Fetch, cache, update, and wrangle all forms of async data in your TS/JS, React, Vue, Solid, Svelte & Angular applications all without touching any “global state”

TanStack Query は非同期通信処理のキャッシュ戦略やリトライ管理を一手に引き受けてくれてくれるライブラリで、導入しているプロジェクトは多いのではないかと思います。

アウェアファイでは、クライアント - サーバーの通信に Connect / gRPC / Protocol Buffers を採用しているのですが、Connect for TanStack Query なるライブラリも登場しているようで、導入を検証中です。

Connect for TanStack Query | Connect
Connect-Query is a wrapper around TanStack Query (formerly React Query), written in TypeScript and thoroughly tested. It enables effortless communication with servers that speak the Connect Protocol.

TanStack Store

React でアプリケーションを開発するにあたり状態管理ライブラリの選定はしばしば課題になります。本稿執筆時点では、TanStack Query と useState、および Context のみで状態管理を行っています。より複雑な状態管理のユースケースが生じた場合、TanStack Store を候補にしつつ再検討を行う予定です。

TanStack Store
The immutable-reactive data store that powers the core of TanStack libraries and their framework adapters.

Ditox

アウェアファイではモバイル、Web、バックエンド共通して DDD + オニオンアーキテクチャをソフトウェアアーキテクチャとして採用しています。今回プロジェクトにおいて、Dependency Injection(DI)のライブラリを、そもそも使うかどうかも含めて検討を行いました。結果的には Ditox を採用しました。

Ditox.js
Dependency injection for modular web applications

TypeScript の DI ライブラリには幾つか選択肢があり、tsyringInversifyJS がよく使われている印象です。悩みの種となったのが、これらの DI ライブラリは TypeScript のデコレータを利用しており、TypeScriptにおいてデコレータは実験的機能な位置づけのため、ビルドを通すために迂回設定が必要になる点がありました。将来的にもデコレータが正式採用されるかどうか不透明で、負債となる懸念もありました。そのためデコレータを利用しないライブラリを利用するか、DIを利用しないまたは独自で実装するという選択肢が残りました。

Ditox はデコレータを使わず、型安全に DI の機能を提供するライブラリです。DI ライブラリ全般がそうなりがちですが、ボイラープレートが多いと感じることかがあるかも知れません。個人的には許容範囲ではあるのですが、議論の余地の多い技術選定であろうことも理解しています。

React Hook Form + Valibot

React Hook Form (RHF) は React でフォームUI を構築するにあたり定番のライブラリです。

React Hook Form - performant, flexible and extensible form library
Performant, flexible and extensible forms with easy-to-use validation.

RHF はフォーム入力内容のバリデーションを行う目的で zod と一緒に導入されることが多いと思います。今回は "より軽量" を謳う Valibot を導入しました。

Valibot: The modular and type safe schema library
Validate unknown data with Valibot, the open source schema library with bundle size, type safety and developer experience in mind.

TypeScript のバリデーションライブラリの共通インターフェースを規格するプロジェクトである Standard Schema の動きも注目が集まっているようですが、Valibot もそのリストに加わっています。使用感としてはよく、シンプルかつ柔軟にバリデーションロジックを定義できます。

const LoginSchema = v.object({
  email: v.pipe(
    v.string(),
    v.nonEmpty('Emailアドレスを入力してください'),
    v.email('正しいフォーマットのEmailアドレスを入力してください'),
  ),
  password: v.pipe(
    v.string(),
    v.nonEmpty('パスワードを入力してください'),
  ),
});

なお、TanStack Form という TanStack シリーズに RHF 相当のライブラリがありとてもよさそうなのですが、細かい部分で RHF に優れた点があり RHF を採用しました。

react-i18next

国際化対応のためのライブラリについては選定が難航しましたが、結局定番の react-i18next に落ち着きました。

Introduction | react-i18next documentation

他の候補として、typesafe-i18nLinguiParaglide JS を検討しましたが、メンテナンスの継続性や動作やセットアップの安定性、機能などの面から採用を見送りました。

個人的に Flutter 向けの i18n ライブラリの選定を行っていたのが記憶に新しいのですが、TypeScript 向け i18n のほうが選定が難しかった印象です。

参考 :

Flutter の i18n パッケージは slang が良かった件

Vercel

Vercel は紹介する必要のないほどメジャーなフロントエンドアプリのホスティングサービスです。今回、メタフレームワークが Next.js ではないことから、Vercel の採用可否を最後まで悩み、検討していました。

比較対象の中で最も情報が多いことと、Next.js でないことによるデメリットを受けないであろうという見立てのもと、採用に至りました。

TanStack Start を採用したアプリが問題なくできることを優先事項に検証を行っていまして、他に候補となっていたサービスを紹介します。

Scale & Ship Faster with a Composable Web Architecture | Netlify
Realize the speed, agility and performance of a scalable, composable web architecture with Netlify. Explore the composable web platform now!

Netlify も Vercel 同様フロントエンドアプリのホスティングサービスです。Vercel と甲乙付けがたかったのですが、Netlify の CDN には日本リージョンが含まれていないという状況が以前から継続しているようで、強いて言えばの懸案ポイントになりました。

Cloud Application Platform | Render
On Render, you can build, deploy, and scale your apps with unparalleled ease – from your first user to your billionth.

Render.com は バックエンドサービスの運用全般を支えるサービスです。Webアプリの実行環境以外にもデータベースを立ち上げることができ、コミュニティでは Heroku と比較されることが多いようです。興味深いプロジェクトではあったものの、今回はWebフロントエンドアプリがデプロイできればよくデータベース構築などのニーズはなかったため、不採用となりました。

なお Cloudflare Pages については、TanStack Start のドキュメントにもホスティング先として記載があるものの今回の検証の範囲では正常動作を確認することができず断念しました(過去にも、そんなことが、あったような...)。

ほか

TanStack Start を採用すると、Vite(自分用 : ヴィートと読む)および Vinxi(自分用 : ヴィンチと読む)を利用することになります。

GitHub - nksaraf/vinxi: The Full Stack JavaScript SDK
The Full Stack JavaScript SDK. Contribute to nksaraf/vinxi development by creating an account on GitHub.

Vitest はテスティングフレームワークとしてよく選択され、E2E テストでは Playwright が最有力選択肢と理解していたので特に深追いせずに採用しています。

Vitest
Next generation testing framework powered by Vite
Fast and reliable end-to-end testing for modern web apps | Playwright
Cross-browser end-to-end testing for modern web apps

こぼれ話 : SolidJS および Solid Start について

じつは今回の技術選定の前段階として、アプリのプロトタイプを React ではなく SolidJS で開発していました。

GitHub - solidjs/solid: A declarative, efficient, and flexible JavaScript library for building user interfaces.
A declarative, efficient, and flexible JavaScript library for building user interfaces. - solidjs/solid

SolidJS にもメタフレームワークがあり、有力なものが Solid Start です。Solid Startは、TanStack Start と TanStack Router の関係のように(命名も似ていますね!)Solid Router を利用しながら SSR の機能を提供するためのメタフレームワークです。Solid Start も Vinxi を利用しています。

SolidStart: Fine-Grained Reactivity goes fullstack
SolidStart is a JavaScript Framework designed to build SolidJS apps and deploy them to a variety of providers.

SolidJS および Solid Start の開発体験そのものは非常によく、React と比較して軽量であったり、そもそもの設計が アンチパターンを誘発させないように配慮されていたり、状態管理についても Signals の一択で悩む余地がないなど、多くの魅力をもった技術スタックと言えます。

しかしながら、React エコシステムの大きさと比べたときに前衛的すぎるのではないかという点、特にUIライブラリの充実度合いが課題となり採用は見送りました。UIライブラリに関して、shadcn の SolidJS 版にあたる shadcn-solid という非公式プロジェクトや Park UI という魅力的なプロジェクトがあるものの、選択肢が非常に限られ、ゼロから自分たちで構築していく覚悟が必要とされるであろうことが憂慮事項としてあがっていました。

Home | Park UI
Beautifully designed components built with Ark UI and Panda CSS that work with a variety of JS frameworks.

この文章量のバランスからして SolidJS を採用できなかった残念さが滲み出ているかと思いますが…。

さておき、特に今後、UIコンポーネントはAIのコーディング支援を受けて開発する機会が多くなるであろうことから、"AIが詳しい" 技術スタックに寄せることのメリットがさらに大きくなっていくと考えます。例えば v0 の支援を受けやすい React + shadcn の採用を後押しする根拠になるでしょう(といいつつ Next.js を採用していなかったりしますけれど)。

v0 by Vercel
Chat with v0. Generate UI with simple text prompts. Copy, paste, ship.

まずミニマムでリプレースを向かえたアウェアファイWebアプリ、今後、機能の拡充を急ピッチで進めていく計画です。アウェアファイでは、AI x ヘルスケア領域で、モダンな技術スタックで熱量高く & 楽しみながらプロダクト開発に取り組みたいエンジニアを募集しています。