技術公開日 更新日

【Laravel→TS移行記】TypeScriptのメリットと選定基準 ーバックエンドもNext.jsー

先に結論

  • TypeScript採用のメリットは フロントとバックエンドの言語と型の共有
  • Web で完結する事業立ち上げ(少人数)なら、Next.js 単独がいい (バックエンドもNext.js)
  • 複数のクライアント(Web + モバイルなど)を伴う場合は、NestJS + Next.js
  • フロントを持たない純粋な API サーバーなら、そもそも TypeScript でなくてもいい(Go なども選択肢に入る)

はじめに

このシリーズ【Laravel→TS移行記】では、Laravel 歴 10 年の私が TypeScript スタック(Next.js / NestJS / Prisma)に移行していく過程を記録しています。

ここまでで、NestJS + Next.js + Prisma の構成で一通り動くものを作り、設計や命名規約まで固めました。また、Next.js単独(+ Prisma) でも同様に動くものと設計・命名規則まで固めて比較してみました(その記事は後日公開します)。
それを踏まえて、今回はTypescript選定のメリットと選定基準については考えてみたいと思います。

** この記事ではTypeScript選定のメリットとTypeScritpで採用すべきフレームワークの基準を考えます **

なぜ TypeScript なのか?

TypeScript採用のメリットはフロントエンドとバックエンドの言語・型定義の共有です。

私が PHP/Laravelから TypeScript へ移行するにあたって、これがTypescriptの一番のメリットと感じます。API のリクエスト・レスポンスの形を1箇所(zod スキーマ)で定義すれば、フロントの入力検証も、バックの検証も、型も、API ドキュメントも一元管理でき、「タイトルは必須」というルールを二度書かなくていいのはかなり心地よい開発体験です(開発工数も減ります)。

Laravel + Vue の頃は、フロントにTypescriptを採用するとバックエンドの型(PHP)と2重の型定義が発生してしまうので、あえてTypescriptを採用せずフロント側の型定義の手間を省いていました(ツールである程度の自動化が可能ですがそれも面倒)。これはタイプセーフな実装とのトレードオフになります。

Typescriptのメリットがタイプセーフな言語でフロントエンドとバックエンドの言語・型定義を共有できる、ということは裏を返せばフロントエンドがTypescript(Next.jsやVue.jsなど)でなければバックエンドでTypescriptを採用する理由が薄くなるということにもなります。
ここがTypescriptを採用するかどうかの基準になりますね。

次にTypescript絡みでの技術選定基準を考えてみましょう。

選定を分ける2つの軸

TypeScriptを考えた場合の技術選定基準は以下の2つを軸に考えると整理できると思います。

  • 軸①:フロント(UI)を持つか ── Web サービスなのか、フロントを持たない純 API サーバーなのか
  • 軸②:クライアントは単一か複数か ── Web だけで完結するのか、Web + モバイルなど複数の形式を考えるか

この2軸で、構成は大きく3パターンに分かれます。

ケース 構成 ざっくりした理由
Web で完結・単一クライアント Next.js 単独 型共有もプロセスも最小。モノリシックで単純
Web + 別クライアント(複数) NestJS + Next.js API を共有。型も共有できるがコストが増える
フロントを持たない純 API Go なども候補 型共有の旨味が消えるので、性能で選べる

以降、それぞれを見ていきます。

ケース1:Web で完結するなら Next.js 単独

私はこのケースを主軸として考えています。ブラウザで完結する Web サービス、特に少人数(1人〜数人)での事業立ち上げなら、Next.js 単独がいいです。

理由は3つ。

言語統一でスイッチングコストがない

フロントもバックも TypeScript。これは「型共有できる」以上に1日の中でフロントとバックを行き来しても、言語の頭の切り替えが発生しないというメリットがあります。Laravel + Vue の頃は、PHP と JavaScript を行き来するたびに小さな切り替えコストがありました。少人数だと一人が両方を触るので、この統一は地味に効きます。VSCodeなどエディタにはTypescriptのプラグインだけインストールすれば良いのも良いです。

モノリシックの単純さ

Next.js 単独なら、1プロセス・1デプロイです。App Router の Server Component や Server Action を使えば、フロントとサーバーのやり取りがフレームワークの中で完結し、CORS の設定すら要りません(サーバー内で完結するので)。

これは NestJS + Next.js と Next.js 単独でそれぞれ技術検証した結果かなり大きいメリットだと感じました。これは次の項目で詳しく書きます。

型共有のコストがほぼ無い

この理由がかなり大きく、例え同じTypescriptで NestJS(バック)と Next.js(フロント)を組んでも型共有のために packages/shared などの共有するためのディレクトリを切り出すなどの設計が必要になります。

この設計は以下の手間も含んでいて

  • 共有パッケージを CJS と ESM の両方でビルドするデュアルビルドが必要
  • ブラウザから API を叩くときの CORS 設定が必要
  • バックとフロントで2系統のデプロイが必要

これらは「バックとフロントが別プロセスに分かれている」ことから来るコストでした。

Next.js 単独なら、これらの手間はまるっとなくなるので、もはやNext.js 単独でいけるならNext.js 単独一択なのでは?と思うようになりました。コード管理も一元化でき、これは特に少人数チームに効果的だと思いました。

※ だたしNext.jsのみの開発・運用は注意点があるのでこれは後述します

ケース2:複数クライアントがあるなら NestJS + Next.js

フロントエンドとバックエンドを分けないといけない、そしてどちらもTypescriptが最適なパターンはなんでしょう?
これについては、WebとしてNext.jsを採用しつつネイティブアプリや他システム連携のためにAPIを提供する必要があるときになりますね。

この場合はAPI を独立したバックエンドサーバー(NestJS)として立てて、APIサーバーとしての役割と果たしつつ、フロントは Next.js で packages/shared など共有ディレクトリを作って バックエンドのAPIサーバーと型定義などを共有することができます。

ただし、デュアルビルド・CORS・2系統デプロイのコストが発生するので、これは複数クライアントに配るための必要なコストと割り切らないといけないですね。

逆に言えば、複数クライアントの予定がないのに最初から NestJS + Next.js で組むのは、払わなくていいコストを払ってしまっているとも言えます。私自身、NestJS + Next.jsとNext.js単独をそれぞれ検証しましたが 、Web 完結の事業やMVPなどの事業立ち上げやトライアルなら Next.js 単独を選ぶと思います。

ケース3:フロントを持たない純 API なら、TypeScript でなくてもいい

最後に、もし作るものがフロントを持たない(ネイティブアプリ用などの)、純粋な API サーバーだったら。この場合、TypeScript を選ぶ一番の理由――フロントとバックの型共有――がなくなるため、他言語など自分やチーム・組織の実績があって馴染みがある言語を採用しましょう。

型共有のメリットがなくなるとTypeScript を選ぶ理由もなくなるので、Go を筆頭にバックエンドに適した言語が候補になってくると思います(もちろん会社・組織・チームの運用やエンジニアの志向などを考慮したうえでTypescriptになることもあると思います)。

TypeScriptがフロントのデファクトスタンダードになっている現状で、バックエンドとの型共有は特に少人数開発で大きなメリットをもたらしますが、フロントエンドとセットで考えなくて良いのであれば採用理由は薄れてしまいますね。

Next.js単独の場合の考慮点

Next.jsを単独で採用する場合、以下については考慮が必要です。

  1. 定期バッチ実行の仕組みがない
  2. バックエンド(server action)とフロントエンド(client)を明確に分離しないとテストしづらくなる

特に1のNext.jsは定期バッチの仕組みがないことは注意が必要で、AWSであればEventBridge + ECS Scheduled Taskで定時にバッチを起動する仕組みを作るなどの必要があります。
また、バッチの重複実行やバッチの突き抜けを回避するための仕組みも自前で作る必要があるため多少の手間がかかります。

Laravelではこれらを回避する仕組みがフレームワークで用意されていましたが、Next.jsではありません。

技術選定はNext.js単独を中心に考える

それでも私の現状の中心技術に据えたいと思うのは、Web で完結する少人数の事業なら、Next.js 単独 ですね。

理由はシンプルで、バッチの仕組みなどを自前で組む手間はあるが、「言語統一」と「モノリシックの単純さ」から得られるメリットの方が大きいからです。

言語統一とモノリシックの単純さは、開発している間ずっと効き続けるメリットです。頭の切り替えがない、プロセスが1つ、デプロイが1系統、CORS を考えなくていい――この単純さが、少人数開発では毎日効いていると実感しています。
開発や運用の引き継ぎを考えた場合もNext.jsができるエンジニア1人を採用すれば回ることも大きいですね(作業量が大きい場合でもAIを活用すれば1人でなんとかなる)。

そして、スケールした場合でもバックエンドとフロントエンドの境界線をはっきりしておけば、バックエンド部分だけを少ない工数で切り出すことも可能です。

立ち上がりが早くて手離れもいいので、まずはNext.js単独で事業を立ち上げてみようと手軽に思えるのもよいです。

まとめ

TypeScript でやるなら何を選ぶか、を選定の物差しで整理しました。

問い 答え
なぜ TypeScript か フロントとバックの型共有。ただしフロントがいてこそ
Web で完結・少人数 Next.js 単独(言語統一・モノリシックの単純さ)
複数クライアント NestJS + Next.js
フロントを持たない純 API 型共有の旨味が消える → Go なども候補

大きな捉え方としては、**「TypeScript を選ぶ最大の理由は型共有で、その旨味が最大化するのは Web 完結・少人数の Next.js 単独構成」**ということです。新規事業や小規模開発を多くこなしてきた私からすると手間なくすっとWebが作れるNext.js単独は魅力的ですね。

次回は、この「Next.js 単独」を実際に選んだ前提で、私が Next.js で AI コーディングをする際に作ったプロジェクト規約を紹介します。少人数開発で AI にコードを書かせるなら、規約こそが品質の生命線になる、という話です。

← 記事一覧に戻る