turbo (Turborepo) の使い方 — JavaScript/TypeScript モノレポの高速ビルドシステム
一言でいうと
Turborepo は、JavaScript / TypeScript のモノレポ(monorepo)向けに設計された高速ビルドシステムです。Rust で書かれており、インテリジェントなキャッシュとタスクの並列実行により、ビルド・テスト・リントなどのタスクを劇的に高速化します。
どんな時に使う?
- モノレポで複数パッケージを管理している時 — フロントエンド、バックエンド、共有ライブラリなどを1つのリポジトリで管理し、依存関係を考慮した効率的なビルドパイプラインを構築したい場合
- CI/CD のビルド時間を短縮したい時 — リモートキャッシュを活用して、変更のないパッケージのビルドをスキップし、CI の実行時間とコストを削減したい場合
- チーム開発でビルドキャッシュを共有したい時 — 他のメンバーが既にビルドした成果物をリモートキャッシュ経由で再利用し、ローカル開発の待ち時間を短縮したい場合
インストール
# npm
npm install turbo --save-dev
# yarn
yarn add turbo --dev
# pnpm
pnpm add turbo --save-dev
グローバルインストール(推奨)
# npm
npm install turbo --global
# yarn
yarn global add turbo
# pnpm
pnpm add turbo --global
Tips: グローバルインストールすると
turboコマンドをどこからでも実行できます。プロジェクトルートにもdevDependencyとして入れておくと、CIでの再現性が確保できます。
新規モノレポの作成
npx create-turbo@latest my-monorepo
基本的な使い方
プロジェクト構成例
my-monorepo/
├── apps/
│ ├── web/ # Next.js アプリ
│ └── api/ # Express サーバー
├── packages/
│ ├── ui/ # 共有UIコンポーネント
│ ├── config/ # 共有設定
│ └── tsconfig/ # 共有TypeScript設定
├── turbo.json # Turborepo 設定ファイル
├── package.json
└── pnpm-workspace.yaml
turbo.json の基本設定
// turbo.json
{
"$schema": "https://turborepo.dev/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"]
},
"test": {
"dependsOn": ["build"],
"inputs": ["src/**", "test/**"]
},
"lint": {
"dependsOn": ["^build"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}
タスクの実行
# 全パッケージのビルドを実行
turbo build
# 全パッケージのテストを実行
turbo test
# 開発サーバーを起動
turbo dev
# 複数タスクを同時に実行
turbo build lint test
よく使う設定・コマンド
1. タスク依存関係の定義(dependsOn)
タスク間の依存関係を宣言的に定義します。^ プレフィックスは「依存パッケージの同名タスクを先に実行する」ことを意味します。
// turbo.json
{
"tasks": {
"build": {
// 依存パッケージの build が完了してから自身の build を実行
"dependsOn": ["^build"]
},
"test": {
// 自パッケージの build が完了してから test を実行
"dependsOn": ["build"]
},
"deploy": {
// 自パッケージの build と test が完了してから deploy を実行
"dependsOn": ["build", "test"]
}
}
}
2. キャッシュ出力の指定(outputs)
キャッシュに保存するファイル・ディレクトリを指定します。キャッシュヒット時にこれらが復元されます。
{
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": [
"dist/**",
".next/**",
"!.next/cache/**" // .next/cache は除外
]
},
"generate": {
"outputs": ["src/generated/**"]
}
}
}
3. フィルタリング(--filter)
特定のパッケージやその依存関係のみを対象にタスクを実行します。
# web パッケージのみビルド
turbo build --filter=web
# web パッケージとその依存パッケージをビルド
turbo build --filter=web...
# apps/ 配下のパッケージのみビルド
turbo build --filter="./apps/*"
# 前回のコミットから変更があったパッケージのみビルド
turbo build --filter="...[HEAD^1]"
# 特定パッケージを除外
turbo build --filter="!@repo/docs"
4. 環境変数の管理(env / globalEnv)
環境変数をキャッシュキーに含めることで、環境変数の変更時にキャッシュを無効化できます。
{
// 全タスクに影響するグローバル環境変数
"globalEnv": ["CI", "NODE_ENV"],
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"],
// このタスク固有の環境変数
"env": [
"API_URL",
"DATABASE_URL"
]
}
}
}
5. リモートキャッシュの設定
チームメンバーやCI間でビルドキャッシュを共有できます。
# Vercel のリモートキャッシュにログイン
turbo login
# リモートキャッシュをリンク
turbo link
# リモートキャッシュを利用してビルド
turbo build
// turbo.json(セルフホスト環境の場合)
{
"remoteCache": {
"enabled": true,
"apiUrl": "https://your-cache-server.example.com"
}
}
補足: よく使うCLIオプション
# ビルドの依存関係グラフを可視化
turbo build --graph
# 並列実行数を制限
turbo build --concurrency=4
# キャッシュを無効化して強制実行
turbo build --force
# ドライラン(実際には実行しない)
turbo build --dry-run
# 実行サマリーを出力
turbo build --summarize
類似パッケージとの比較
| 特徴 | Turborepo | Nx | Lerna |
|---|---|---|---|
| 言語 | Rust | TypeScript | TypeScript |
| セットアップの容易さ | ◎ 非常に簡単 | △ 学習コスト高め | ○ 比較的簡単 |
| ビルドキャッシュ | ◎ ローカル+リモート | ◎ ローカル+リモート(Nx Cloud) | △ 限定的 |
| タスク並列実行 | ◎ | ◎ | ○ |
| 設定ファイル | turbo.json のみ | nx.json + project.json 等 | lerna.json |
| プラグインエコシステム | △ 最小限 | ◎ 豊富 | △ 最小限 |
| パッケージマネージャ | npm/yarn/pnpm | npm/yarn/pnpm | npm/yarn/pnpm |
| 開発元 | Vercel | Nrwl | 現在は Nx が管理 |
選定の目安:
- Turborepo — シンプルな設定で高速なキャッシュ・並列実行が欲しい場合。既存モノレポへの導入が容易
- Nx — 大規模プロジェクトでコード生成やプラグインによる高度な自動化が必要な場合
- Lerna — パッケージのバージョニング・公開が主目的の場合(ビルドシステムとしてはTurborepoやNxと併用が推奨)
注意点・Tips
1. outputs の指定漏れに注意
outputs を正しく設定しないと、キャッシュヒット時にビルド成果物が復元されません。新しいビルド出力先を追加した場合は必ず turbo.json も更新してください。
// ❌ outputs 未指定 → キャッシュから復元されない
{
"tasks": {
"build": {
"dependsOn": ["^build"]
}
}
}
// ✅ outputs を明示的に指定
{
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
}
}
}
2. dev タスクにはキャッシュを無効化する
開発サーバーのような長時間実行タスクはキャッシュ不要です。persistent: true を設定すると、他のタスクがこのタスクの完了を待たなくなります。
{
"tasks": {
"dev": {
"cache": false,
"persistent": true
}
}
}
3. ルートの package.json に turbo を含める
// package.json(ルート)
{
"devDependencies": {
"turbo": "^2.9.4"
},
"scripts": {
"build": "turbo build",
"dev": "turbo dev",
"lint": "turbo lint",
"test": "turbo test"
}
}
4. .gitignore にキャッシュディレクトリを追加
# Turborepo
.turbo
5. CI での活用例(GitHub Actions)
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "pnpm"
- run: pnpm install
- run: pnpm turbo build lint test --filter="...[origin/main]"
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
6. inputs でキャッシュの精度を上げる
デフォルトではGitで追跡されている全ファイルがキャッシュキーに含まれます。inputs を指定すると、関連ファイルの変更時のみキャッシュが無効化されます。
{
"tasks": {
"test": {
"inputs": ["src/**", "test/**", "jest.config.*"],
"outputs": ["coverage/**"]
},
"lint": {
"inputs": ["src/**", ".eslintrc.*"],
"outputs": []
}
}
}
注意: この記事は Turborepo v2.x 系(v2.9.4)を基に記述しています。v1.x からはいくつかの破壊的変更があります(例:
pipeline→tasksへのリネームなど)。
まとめ
Turborepo は、turbo.json 1ファイルの設定だけでモノレポのビルド・テスト・リントを劇的に高速化できるビルドシステムです。Rust ベースの高速な実行エンジン、インテリジェントなキャッシュ、宣言的なタスク依存関係の定義により、既存プロジェクトへの導入コストを最小限に抑えながら大きなパフォーマンス改善が得られます。特に CI/CD パイプラインでのリモートキャッシュ活用は、チーム全体の開発生産性を向上させる強力な武器になるでしょう。