はじめに
TanStack Routerを触ってみて「型安全なルーティング、これいいな」と思った方、次のステップとしてTanStack Startが気になっているんじゃないでしょうか。
TanStack Startは、TanStack Router上に構築されたフルスタックフレームワークです。月間60万ダウンロード、GitHubで12,500スター以上という数字を見ると、単なる実験的プロジェクトではないことがわかります。
正直なところ、フルスタックフレームワークといえばNext.jsがデファクトスタンダードになっている状況で、あえて別の選択肢を検討する意味があるのか、最初は半信半疑でした。でも実際に触ってみると、「クライアント優先」という設計思想が刺さる人には刺さるフレームワークだと感じています。
TanStack Startとは
TanStack Startは、TanStack Query(旧React Query)やTanStack Routerを開発したTanner Linsley氏率いるチームが手がけるフルスタックフレームワークです。現在はRelease Candidate(RC)段階で、ベータ版として利用可能。
コンセプトは「Client-first, server-capable」。クライアントサイドの開発体験を最優先しながら、サーバーサイドの機能もフルに活用できる設計になっています。
ReactとSolidに対応しており、ビルドツールにはViteを採用。ViteのおかげでHMRが爆速だし、Viteのエコシステムをそのまま活用できるのもメリットです。
ちなみに、100%オープンソースでMITライセンス。TanStack LLCは自己資金で運営されており、Cloudflare、Netlify、Neonなどの企業と提携して開発を継続しています。
特徴・メリット
1. TanStack Routerの型安全性をそのまま継承
TanStack Startの土台はTanStack Router。つまり、あの「エンドツーエンドの型安全性」がフルスタックでも活きてきます。
ルートパス、URLパラメータ、検索パラメータ、ローダーの戻り値。全部が型で守られている状態で、さらにServer Functionsまで型安全に呼び出せる。これ、開発体験としてはかなり気持ちいいです。
2. フルドキュメントSSRとストリーミング
サーバーサイドレンダリングは当然サポート。それに加えて、ストリーミングにも対応しているので、初期表示を高速化しつつ、重いデータは後から流し込むといった最適化が可能です。
SEOが重要なサイトや、初期表示速度がKPIになっているプロジェクトには嬉しい機能ですね。
3. Server Functions(型安全なRPC)
個人的には、これがTanStack Startの一番の魅力だと思っています。Server Functionsを使うと、サーバー上で実行される関数をクライアントから型安全に呼び出せます。
tRPCのような型安全なRPCを、フレームワークレベルで統合している感じ。別途ライブラリを追加する必要がないのはQOL上がりますね。
4. どこにでもデプロイ可能
「Can be deployed anywhere JS can run」が公式のキャッチフレーズ。Viteベースなので、従来型のサーバー、サーバーレス、エッジ、CDNなど、さまざまな環境にデプロイできます。
Vercelに縛られないのは、インフラの選択肢を残しておきたい場合にありがたい。
5. Viteエコシステムとの親和性
ビルドツールがViteなので、Viteのプラグインやエコシステムをそのまま活用できます。設定もViteベースなので、既存のViteプロジェクトからの移行もスムーズ。
開発サーバーの起動も爆速。30代になると、待ち時間が地味にストレスになるので、ここは重要なポイントです。
インストール方法
新規プロジェクトの作成
CLIツールを使うのが一番簡単です。
# pnpm(推奨)
pnpm create @tanstack/start@latest
# npm
npm create @tanstack/start@latest
対話形式で、Tailwind CSS、ESLint、その他のオプションを選択できます。
既存の例からクローン
すぐに動くものを試したい場合は、公式の例をクローンするのが手っ取り早いです。
npx gitpick TanStack/router/tree/main/examples/react/start-basic start-basic
cd start-basic
npm install
npm run dev
公式には10以上の例が用意されています。
- Basic — 基本的なセットアップ
- Basic + React Query — データ取得の統合
- Clerk Auth — 認証実装
- Supabase — Supabase連携
- Convex + Trellaux — リアルタイムデータベース
個人的には、まずBasicで動作を確認してから、必要な機能を追加していくアプローチがおすすめです。
基本的な使い方
プロジェクト構造
TanStack Startのプロジェクトは、基本的に以下のような構造になります。
my-app/
├── app/
│ ├── routes/
│ │ ├── __root.tsx # ルートレイアウト
│ │ ├── index.tsx # ホームページ
│ │ └── about.tsx # Aboutページ
│ ├── client.tsx # クライアントエントリー
│ ├── router.tsx # ルーター設定
│ └── ssr.tsx # SSR設定
├── app.config.ts # アプリ設定
├── package.json
└── tsconfig.json
ファイルベースルーティングを採用しているので、routes/ディレクトリにファイルを置くだけでルートが生成されます。
ルーターの設定
// app/router.tsx
import { createRouter as createTanStackRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
export function createRouter() {
const router = createTanStackRouter({
routeTree,
})
return router
}
declare module '@tanstack/react-router' {
interface Register {
router: ReturnType<typeof createRouter>
}
}
routeTree.genは、ファイルベースルーティングから自動生成されるファイルです。手動でルートを定義する必要がないのは楽ですね。
ルートコンポーネントの作成
// app/routes/index.tsx
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/')({
component: Home,
})
function Home() {
return (
<div>
<h1>Welcome to TanStack Start</h1>
<p>フルスタック開発を始めよう</p>
</div>
)
}
createFileRouteでルートを定義し、componentにコンポーネントを渡すだけ。シンプルです。
データローダーの活用
// app/routes/users.$userId.tsx
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/users/$userId')({
loader: async ({ params }) => {
const response = await fetch(`/api/users/${params.userId}`)
if (!response.ok) throw new Error('User not found')
return response.json()
},
component: UserDetail,
})
function UserDetail() {
const user = Route.useLoaderData()
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
)
}
ローダーで取得したデータは、useLoaderDataで型安全に取得できます。パラメータも型推論が効くので、タイプミスによるバグを防げます。
Server Functionsの使用
// app/routes/contact.tsx
import { createFileRoute } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/start'
import { z } from 'zod'
// Server Functionの定義
const submitContact = createServerFn('POST', async (data: {
name: string
email: string
message: string
}) => {
// サーバーサイドでのみ実行される
console.log('Received contact form:', data)
// データベースへの保存やメール送信などの処理
// await db.contacts.create({ data })
return { success: true }
})
export const Route = createFileRoute('/contact')({
component: ContactForm,
})
function ContactForm() {
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
const formData = new FormData(e.currentTarget)
const result = await submitContact({
name: formData.get('name') as string,
email: formData.get('email') as string,
message: formData.get('message') as string,
})
if (result.success) {
alert('送信しました')
}
}
return (
<form onSubmit={handleSubmit}>
<input name="name" placeholder="お名前" required />
<input name="email" type="email" placeholder="メールアドレス" required />
<textarea name="message" placeholder="メッセージ" required />
<button type="submit">送信</button>
</form>
)
}
createServerFnで定義した関数は、サーバーサイドで実行されます。クライアントからは通常の関数呼び出しのように使えるのに、実際にはRPCとして動作する。これ、意外とスッキリ書けます。
実践的なユースケース
1. 管理画面・ダッシュボード
型安全なルーティングと検索パラメータ管理が活きるユースケース。フィルター条件やページネーションをURLで管理することで、状態の共有やブックマークが容易になります。
Server Functionsを使えば、複雑なデータ集計もサーバーサイドで処理できるので、クライアントに重い処理を押し付けずに済みます。
2. ECサイト・ポートフォリオ
SSRとストリーミングが活きるユースケース。商品一覧は即座に表示しつつ、在庫情報や価格情報は後からストリーミングで流し込む、といった最適化が可能です。
SEO対策が重要なサイトには、SSRのメリットが大きいですね。
3. SaaS・Webアプリケーション
認証やデータ管理が必要なアプリケーションに最適。ClerkやSupabaseとの連携例が公式に用意されているので、スタートダッシュが切りやすい。
型安全なServer Functionsのおかげで、バックエンドとフロントエンドの境界がスムーズになります。
Next.jsとの比較
正直なところ、Next.jsは成熟度が高く、情報量も圧倒的に多いです。迷ったらNext.jsを選んでおけば間違いない、というのは事実。
ただ、TanStack Startには以下のような特徴があります。
- 型安全性の徹底度: TanStack Routerベースなので、ルーティング周りの型安全性はTanStack Startの方が上
- クライアント優先の設計: SPAっぽい開発体験を維持しながらSSRも使いたい場合に向いている
- Viteベース: ビルド速度やHMRの体験が良い
- デプロイ先の自由度: Vercelに縛られない
一方、React Server Components(RSC)には現時点で対応していないのがデメリット。公式は開発中とのことですが、RSCが必須要件ならNext.jsを選ぶべきでしょう。
まとめ
TanStack Startは、以下のような開発者に向いているフレームワークです。
- TanStack Routerの型安全性が気に入っている
- クライアント優先の開発体験を大事にしたい
- Viteベースの快適な開発環境が欲しい
- デプロイ先の選択肢を残しておきたい
現時点ではRC段階なので、本番環境での採用には慎重になる必要があります。ただ、公式は「breaking changesはもう予定していない」と明言しているので、今から学び始めても無駄にはならないでしょう。
30代になって思うのは、技術選定において「みんなが使っているから」という理由だけで選ぶのは、長期的にはリスクになることもあるということ。TanStack Startが自分のプロジェクトに合っているかどうか、一度試してみる価値はあると思います。
まずは公式の例をクローンして、30分ほど触ってみてください。型安全なフルスタック開発の快適さを体感できるはずです。