T3 Stackに見るフロントエンド開発の技術トレンド
しばしば見かけているフロントエンドのT3とはなんぞやと気になってたので整理してみました。また、T3 Stackの解説は素晴らしい記事が他にあったので、フロントエンド全体の潮流についても記述することで付加価値をつけました。
T3(T3 Stack)って何?
T3(T3 Stack)は海外のエンジニア系インフルエンサー?のTheo氏が提唱している、モダンフロントエンド開発におけるシンプルでモジュール性を備えた型安全な開発に焦点を当てた技術スタック及びその思想を指している認識です。
技術スタック部分だけで良いかと思ったものの、スタック自体は入れ替えを想定していたり、いくつかの原則もあるので思想的な要素も加えました。
T3の由来は見つからなかったですが、Typescript、Tailwind CSS、tRPCの頭文字を指しているのではと予想します。
T3の全体像
T3はいくつか分解して考えることができます。(具体的なスタックなどは変更の余地あるといった記述を見かけました。今後アップデートで追加変更はあるかもです。)
①T3 App
T3 Appは、T3 Stackに最適化されたCLIテンプレート(create-t3-app
)です。T3 Appでは新しいWebアプリケーションを型安全で効率的に開発する方法を提供することを目標としています。
// いずれかでサクッと初期構築できます
npm create t3-app@latest
yarn create t3-app
pnpm create t3-app@latest
必要なパッケージと最低限のテンプレートがあらかじめ用意されていて使いやすそうですね。Githubのスター数(執筆時:18.3k)もなかなかあり、フロントエンド界隈で一定の共感を読んでいるものと推察できます。
②T3 Axiom
T3には3つの原則があります。移り変わりの激しいフロントエンド技術の中での基礎方針が示されています。
1.問題解決:Solve Problems
T3に含めるスタックは、ある領域に対して固有の問題を解決することを前提とします。例えば、Auth.js(NextAuth.js)であればフロントエンドの認証問題を解決してくれますが、それ以外には影響を与えません。
技術を詰め込むのではなく、解決すべき課題に対して何を使って解決するかを明示的にすることでモジューラリティを意識した開発を実現します。
zustandなどの状態管理ライブラリ自体は固有の問題を解決しているわけではないので、T3 Stackには含めないといった考えのようです🤔
2.流血の責任:Bleed Responsibly
新しい技術は魅力的であるものの、なんでもかんでも使えばいいというものではありません。Bleed Responsiblyは既存の仕様を壊すことやリラーニングが求められる/他人に求めることに対して責任を持つことを指しているのではと思います。
BDなどの高リスクな領域では慎重に、tRPCを挟むといった低リスクな領域では積極的にリスクを取って果実を得るよう試みます。
3.型安全:Typesafety Isn’t Optional
T3では型安全性を非常に大事にしています。型安全であることは生産性を向上させ、バグの少ないプロダクトを開発することに大きく貢献します。
③T3 Stack
T3 Axiomに則った具体的なスタックです。それぞれどのような役割か把握されていない方もいると思うので簡単にまとめます。
Next.js
1.Next.jsはReactを最大限活かすためのバックエンドフレームワーク(T3上でNext.js is a backend framework for your React applications.と表現されているのを踏襲)です。
ルーティングやAPI作成、画像レンダリングなどWebアプリケーション開発をサポートするさまざまな機能があり、Vercelと組み合わせることで簡単にデプロイまで実行できます。
Next.jsをバックエンドフレームワークと呼ぶのは聞き馴染みがないですが、ユーザーとサーバーを接続する役割を果たしている点でバックエンドフレームワークであるといった感じでした。特に賛同しているわけではないので、詳しくはYouTubeを見てみてください。(Vercel公式動画という...笑)
Typescript
2.Typescriptはjavascriptのスーパーセットで今では完全にデファクト・スタンダードとなりました。ほとんどのプロジェクトで採用しているのではと思います。T3ではTypescriptとともに、ZodやTanstack Queryを活用して型推論を最大活用していくことにも触れられています。
tRPC
3.tRPCを使うと従来のAPIルートやHTTPメソッドへの依存から解放され自由かつ型安全なAPIを記述することができます。これにより高負荷なイテレーションを回してもプロダクトの品質を保つことにも役立つので今非常に注目されています。
だいぶ省略しますが、次のようなコードで今までAPIルーティング、型定義、フックス化といった処理が完結します。
// server/api/routers/user.ts
const userRouter = createTRPCRouter({
getById: publicProcedure.input(z.string()).query(({ ctx, input }) => {
return ctx.prisma.user.findFirst({
where: {
id: input,
},
});
}),
});
// server/api/root.ts
const appRouter = createTRPCRouter({
users: userRouter,
posts: postRouter,
messages: messageRouter,
});
export type AppRouter = typeof appRouter;
ぱっと見るだけだと理解しづらい&説明能力がないので一度触ってみることをおすすめします🙏
Prisma
4.PrismaはTypescriptのためのORM(Object-Relational Mapping)です。例えば、Planetscaleとともに使うと、Prismaのschema.prismaで作成したデータモデルからDB構造を操作できたりします。
また、Prismaクライアントを利用してデータベース操作を効率よく行うことができます。T3のtRPC項目ではPrismaとZodを使う形での例が示されています。
Tailwind CSS
5.Tailwind CSSは事前に用意されたコンポーネントやロジックを必要とせず、クラス名を付与することでスタイルを定義できるユーティリティファーストなCSSフレームワークです。
ChakraUIのようなUIライブラリでスタイリングを行う場合、一見素晴らしい体験に感じますが、UIライブラリで想定されていないスタイルや機能を実装しようとした瞬間に複雑な仕様を理解して調整することが求められます。そしてそれは実際に難しく時間もかかります。
TailwindはピュアなCSSに近いため、こうした問題が起きにくいのが隠れた大きな利点と言えます。
NextAuth.js
6.NextAuth.jsはNext.jsに手軽にセキュアな認証機能を実装できるライブラリです。Next.jsで扱える認証ライブラリの中でも頻繁に利用されている印象です。
確かにNextAuth.js自体は手軽で扱いやすく良い感じであるものの、個人的にはNext.jsまわりの認証ライブラリは結構な数あるので、NextAuth.jsがベストかは疑わしいなと思っています。とはいえ、Bleed Responsiblyの考えに基づくとNextAuth.jsではなく似たような認証ライブラリを選定する意義も見つかりません。
7.環境変数の型定義
最後に環境変数にも正確に型定義を付与しようということで、Zodを使ってsrc/env.mjsに環境変数を整理する方法が紹介されています。process.env.XXXのデータは何もしないとstring | undefinedですが、一手間加えることで設定漏れや記述ミスを防ぐことができます。
t3-envというOSSが配布されていて、ドキュメントも用意されているので自装でも良いかもですが、これを使った方が楽だと思います。
総論
npm create t3-app
を試してみました。いきなり全部容易されているとファイルの役割が明確に理解しにくいので、個人的には一つ一つドキュメント見ながら実装した方が納得感のあるコードになる気がしています。
また、T3 Stackの基本的な仕様を把握していないと構築されたファイルを見て何がなんだか分からなくなるはずで、この場合はT3 Stackの各ドキュメントを見た方が良い気がしています。
スタックや思想的には大きく共感しているものの、個人としてはなかなか使用機会は少なそうです。
近年のフロントエンドの潮流
このT3 Appの考え方は現在のフロントエンドの潮流を汲み取った合理的なものだと感じました。個人的な感想も含まれますが、ここも少し整理してみます。
型安全
Typescriptのおかげで型定義をして型安全性が重要視されたことで、効率的にバグの少ないアプリケーションを開発する土壌ができました。ここは特に深掘る必要はないですね。
コンポーネント指向
プロダクト開発をコンポーネントに分けて行うことは、Reactなどのフロントエンドフレームワークで一般的になりました。従来のモノシリックな開発では小さな変更が全体に影響を及ぼすこともありましたが、コンポーネント単位で開発を進めることで大規模なアプリケーションも効率的に開発でき、修正も容易です。
近年のローコードやノーコードの流れもコンポーネント指向が大きな影響を与えたと考えていて、業界全体でコンポーネント指向での開発が当たり前になったことで、素晴らしいプロダクトが次々と生まれています。
BFF(Backend For Frontend)
BFFではバックエンドからフロントエンド向けに開発APIを提供し、それぞれが切り離された領域で開発を進めることで依存度を軽減することで、アプリケーション全体のUIやUXを重視した自由なインターフェースを構築できたり、クロスプラットフォームアプリケーション開発もしやすくなりました。
FFB(Frontend For Backend)の方式だとちょっとしたUIの変更もバックエンドが絡んで気軽に見た目を変えることができませんでしたが、BFFではフロント側のコード修正のみでUI改善できるので開発フローに大きな変化のあった話かなと思います。
BaaS(Backend as a Service)
フロントエンドエンジニアはバックエンドの構築を苦手としていますが、BaaSを活用することでバックエンド知識がなくてもデータベースやストレージ、認証機能、通知機能などを実装できます。
基本的なDB構築であれば一通り賄うことができ、セキュリティや動作も一定安定していてスケーラビリティもあるので、迅速に安く高品質なプロダクト開発を行えます。
初期スタートアップやプロトタイピング全般にとって重要な存在になってきました。
無課金開発
フロントエンド開発はマルチスタック開発となります。それぞれにお金がかかると地味に出費がかさむというのと、手軽に開発を始めるという観点からもお金はなるべくかけたくありません。
今であればバックエンドの知識がなくてもBaaSでDBを無料で立ち上げられますし、デプロイ含めWebアプリケーションの基本的な機能は全て無料で構築してプロトタイプを開発できますね。こうしたお金をかけない開発を個人的に無課金開発と呼んでいます。
個人開発だと、AWSでサーバー立ち上げて諸々設定して開発を始めたはいいものの、停止してなくて長い間月4,000円とか継続的に飛んだり停止したつもりになって課金されていたりと苦い思いをしているので無闇に使いたくないんですよね。(Vercelなど必要に応じて課金しています)
コロケーション(責務分離)
コンポーネント指向の流れでコロケーションの開発が広まってきています。例えば、コンポーネント単位でフックス、テストなどのコードを管理することで、部分的な開発の責務分離が明確になり、開発しやすさが向上します。
個人的な例でいくと、Next.jsのPage Routerを扱う際に以下のようなディレクトリ設計で置いていたりします。(ページエクステンションで.pageのみページとして認識させる想定です。)
pages
|- posts
|- |- components
|- |- |- |- PostsHeader.tsx
|- |- |- |- PostLikes.tsx
|- |- hooks
|- |- |- useLikes.ts
|- |- tests
|- |- |- posts.test.ts
|- |- index.page.tsx
※共通要素の管理のためsrc直下にもcomponentsフォルダ等は置きます。ページやコンポーネント固有のフックス等の管理を分散させないことで、後からどのコンポーネントやフックスを取得しているか一目瞭然ですね。(実際の構成は開発しやすいよう調整します)
各階層にコンポーネントやフックスなどの情報を整理することで、開発時にどのコードを見れば良いか(むしろ見る必要のないコードが分かることが重要)明示的になって開発しやすさが向上します。
考え方は合ってると思うのですが、ちょっと認識ずれてる点あるかもなので、コロケーションについてはこの記事を参照してください。(めっちゃ良い記事です。)
参考:そのファイル、本当に hooks/・utils/ に入れるんですか? ―― React プロジェクトを蝕む「見かけ駆動パッケージング」
全体として
開発領域に対する理解がないと分かりにくいと思ったのでまとめると、安く、早く、安全で、高品質な開発をしやすい環境が整ってきたことで、プロダクトを作りやすい/依頼しやすい状況となっています。
今後としては、AIが型推論してコードを自動生成してくれる未来は間違いないので、フロントエンドの仕事はコードライティングからコードマネジメントの方向に移行すると考えています。ノーコード化するかどうかはまだ判断を保留にしています。
まとめ
T3 Stackの意識はしてなかったものの、ちょうど個人開発でのスタックがT3と完全に合致していて興味深かったです。
T3 Appの素晴らしい点は、フロントエンドの技術選定は選択肢が多くて悩ましいという問題をテンプレート化して解消してくれることです。海外のエンジニアインフルエンサーの提唱している内容であり、Githubのスター数もあり、ドキュメントも整備されているので一定の安心感を持って採用できます。
フロント主体で開発したいものの個別の技術に拘りがなかったり、そもそも慣れていない方はT3 Stackを参照すると良い感じのスタックで開発を進められると思います。
ただ、途中でも書きましたが、個人的には一つ一つドキュメント見ながら実装した方がコードを理解した上でカスタマイズ等もできるので良い気がしています。
参考
T3のドキュメント: https://create.t3.gg/ja/introduction
Discussion