tanstack-start
TanStack Routerを基盤とした、SSR・ストリーミング・サーバー関数を備えたフルスタックReactフレームワークで、あらゆるホスティングプロバイダーへのデプロイに対応します。
description の原文を見る
Full-stack React framework powered by TanStack Router with SSR, streaming, server functions, and deployment to any hosting provider.
SKILL.md 本文
TanStack Start スキル
概要
TanStack Start は TanStack Router 上に構築された フルスタック React フレームワークで、Vite と Nitro (Vinxi 経由) で駆動されています。サーバーサイドレンダリング、ストリーミング、サーバー関数 (RPC)、ミドルウェア、API ルート、および Nitro プリセットを通じてあらゆるプラットフォームへのデプロイメントを提供します。
パッケージ: @tanstack/react-start
ルータープラグイン: @tanstack/router-plugin
ビルドツール: Vinxi (Vite + Nitro)
ステータス: RC (Release Candidate)
RSC サポート: React Server Components サポートは開発中であり、非破壊的な v1.x 追加として実装予定
インストール & プロジェクトセットアップ
npx @tanstack/cli create my-app
# または手動でインストール:
npm install @tanstack/react-start @tanstack/react-router react react-dom
npm install -D @tanstack/router-plugin typescript vite vite-tsconfig-paths
プロジェクト構造
my-app/
app/
routes/
__root.tsx # ルートレイアウト
index.tsx # / ルート
posts.$postId.tsx # /posts/:postId
api/
users.ts # /api/users API ルート
client.tsx # クライアントエントリー
router.tsx # ルーター作成
ssr.tsx # SSR エントリー
routeTree.gen.ts # 自動生成されたルートツリー
app.config.ts # TanStack Start 設定
tsconfig.json
package.json
設定 (app.config.ts)
import { defineConfig } from '@tanstack/react-start/config'
import viteTsConfigPaths from 'vite-tsconfig-paths'
export default defineConfig({
vite: {
plugins: [
viteTsConfigPaths({ projects: ['./tsconfig.json'] }),
],
},
server: {
preset: 'node-server', // 'vercel' | 'netlify' | 'cloudflare-pages' | など
},
tsr: {
appDirectory: './app',
routesDirectory: './app/routes',
generatedRouteTree: './app/routeTree.gen.ts',
},
})
サーバー関数 (createServerFn)
サーバー関数は、クライアントとサーバー間の型安全な RPC 呼び出しを提供します。
基本的なサーバー関数
import { createServerFn } from '@tanstack/react-start'
// GET (データ取得、キャッシュ可能)
const getUsers = createServerFn()
.handler(async () => {
const users = await db.query.users.findMany()
return users
})
// POST (ミューテーション、副作用)
const createUser = createServerFn({ method: 'POST' })
.validator((data: { name: string; email: string }) => data)
.handler(async ({ data }) => {
const user = await db.insert(users).values(data).returning()
return user
})
Zod バリデーションを使用
import { z } from 'zod'
const updateUser = createServerFn({ method: 'POST' })
.validator(
z.object({
id: z.string(),
name: z.string().min(1),
email: z.string().email(),
})
)
.handler(async ({ data }) => {
// data は完全に型付けされています: { id: string; name: string; email: string }
return await db.update(users).set(data).where(eq(users.id, data.id))
})
ミドルウェア
ミドルウェアの作成
import { createMiddleware } from '@tanstack/react-start'
const loggingMiddleware = createMiddleware().handler(async ({ next }) => {
console.log('リクエスト開始')
const result = await next()
console.log('リクエスト完了')
return result
})
コンテキストを伴う認証ミドルウェア
const authMiddleware = createMiddleware().handler(async ({ next }) => {
const request = getWebRequest()
const session = await getSession(request)
if (!session?.user) {
throw redirect({ to: '/login' })
}
// ハンドラーに型付きコンテキストを渡す
return next({ context: { user: session.user } })
})
ミドルウェアのチェーン
const adminMiddleware = createMiddleware()
.middleware([authMiddleware])
.handler(async ({ next, context }) => {
// context.user は authMiddleware から型付けされています
if (context.user.role !== 'admin') {
throw redirect({ to: '/unauthorized' })
}
return next({ context: { isAdmin: true } })
})
// 使用方法
const adminAction = createServerFn({ method: 'POST' })
.middleware([adminMiddleware])
.handler(async ({ context }) => {
// context: { user: User; isAdmin: boolean }
return { success: true }
})
API ルート (サーバールート)
// app/routes/api/users.ts
import { createAPIFileRoute } from '@tanstack/react-start/api'
export const APIRoute = createAPIFileRoute('/api/users')({
GET: async ({ request }) => {
const users = await db.query.users.findMany()
return Response.json(users)
},
POST: async ({ request }) => {
const body = await request.json()
const user = await db.insert(users).values(body).returning()
return new Response(JSON.stringify(user), { status: 201 })
},
})
SSR ストラテジー
ストリーミング SSR (デフォルト)
export const Route = createFileRoute('/dashboard')({
loader: async () => ({
criticalData: await fetchCriticalData(),
deferredData: defer(fetchSlowData()),
}),
component: Dashboard,
})
function Dashboard() {
const { criticalData, deferredData } = Route.useLoaderData()
return (
<div>
<CriticalSection data={criticalData} />
<Suspense fallback={<Loading />}>
<Await promise={deferredData}>
{(data) => <SlowSection data={data} />}
</Await>
</Suspense>
</div>
)
}
デプロイメント
サポートされているプラットフォーム (Nitro プリセット)
// app.config.ts
export default defineConfig({
server: {
preset: 'node-server', // 自ホスト Node.js
// preset: 'vercel', // Vercel
// preset: 'netlify', // Netlify
// preset: 'cloudflare-pages', // Cloudflare Pages
// preset: 'aws-lambda', // AWS Lambda
// preset: 'deno-server', // Deno Deploy
// preset: 'bun', // Bun
},
})
ベストプラクティス
- すべてのサーバー関数入力にはバリデーターを使用する - ランタイムセーフティと TypeScript 推論
- ミドルウェアを構成する - 認証、ロギング、レート制限などの横断的関心事のため
createServerFnGET を使用する - データ取得用 (キャッシュ可能、プリロード可能)createServerFnPOST を使用する - ミューテーションと副作用用beforeLoadを使用する - ルートレベルの認証ガード用defer()を使用する - TTFB を改善するための非重要データ用- ルーターに
defaultPreload: 'intent'を設定する - インスタントナビゲーション用 - サーバー関数をそれを使用するルートと一緒に配置する
よくある落とし穴
- サーバー関数はクライアント側の変数をクロージャーできません (別々のバンドルに抽出されます)
- サーバー関数から返されるデータはシリアライズ可能である必要があります
- ローダー内で
awaitを忘れるとストリーミングの問題が発生します - サーバーのみのコードをクライアントバンドルにインポートするとビルドエラーが発生します
declare module '@tanstack/react-router'がないと型安全性がすべて失われます
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- tanstack-skills
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/tanstack-skills/tanstack-skills / ライセンス: MIT
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。