For the complete documentation index, see llms.txt. This page is also available as Markdown.

Structuring a Monorepo

Hướng dẫn cấu trúc monorepo với Turborepo — workspace setup, package types, internal packages, exports, và common pitfalls.

Turborepo xây dựng trên Workspaces — tính năng của package manager (pnpm, npm, yarn) cho phép nhóm nhiều packages trong một repo.

1. Minimum Requirements

Một monorepo hợp lệ cần:

  1. Package manager lockfilepnpm-lock.yaml, package-lock.json, yarn.lock, bun.lock

  2. Root package.jsonprivate: true, scripts gọi turbo

  3. Root turbo.json — cấu hình tasks

  4. Workspace declarationpnpm-workspace.yaml hoặc workspaces trong root package.json

  5. package.json trong mỗi package

Cấu trúc thư mục chuẩn:

my-monorepo/
├── apps/
│   ├── web/            # Next.js app
│   ├── docs/           # Documentation site
│   └── api/            # Express/Fastify API
├── packages/
│   ├── ui/             # Shared UI components
│   ├── utils/          # Shared utilities
│   ├── types/          # Shared TypeScript types
│   ├── config-eslint/  # Shared ESLint config
│   └── config-ts/      # Shared tsconfig
├── turbo.json
├── package.json
├── pnpm-workspace.yaml
└── .gitignore

2. Workspace Setup

pnpm

npm / yarn / bun

Lưu ý: Không dùng apps/** hoặc packages/** (nested). Chỉ 1 cấp depth. Nếu cần nhóm sâu hơn: packages/*, packages/group/* và không tạo packages/group/package.json.

Root package.json

3. Anatomy of a Package

Mỗi package gần như một "dự án nhỏ" — có package.json, tooling config, source code riêng.

package.json

exports — thay thế main, hỗ trợ Conditional Exports, tránh barrel files, IDE autocompletion.

Source code

Thường dùng src/ → compile ra dist/ (nếu là Compiled Package).

4. Package Types

Application Packages

  • Deployable (Next.js, Vite, Express...)

  • .env riêng

  • Chạy bằng turbo run dev / turbo run build

Library Packages

  • Chia sẻ code giữa các apps

  • Có thể là Just-in-Time (export TypeScript trực tiếp, zero build) hoặc Compiled (build ra JS)

Tooling Packages

  • ESLint config, tsconfig, GitHub Actions

5. Just-in-Time vs Compiled Packages

Just-in-Time (JIT)

Export TypeScript trực tiếp. App sử dụng sẽ build cùng. Zero config, không cần dependsOn: ["^build"].

Compiled

Cần build trước khi app dùng → cần dependsOn: ["^build"].

6. Internal Package Dependencies

Khai báo dependency giữa các internal packages như package thường:

pnpm workspace protocol (workspace:*) tự động link local packages.

7. Dùng exports thay vì barrel files

Không dùng barrel files (index.ts re-export tất cả). Dùng exports:

Import:

Lợi ích: tree-shaking tốt hơn, compiler không bị overload, IDE autocomplete.

8. Common Pitfalls

  • Không dùng ../ để import package khác — luôn install và import bằng package name

  • Không cần tsconfig.json root — mỗi package tự có tsconfig, shared config ở package riêng

  • Không dùng apps/** trong workspace glob — chỉ 1 level depth

  • Không viết turbo commands trong package scripts — chỉ ở root

  • Lockfile là bắt buộc — nếu thiếu, Turborepo behavior unpredictable

  • Root .env không khuyến nghị — đặt .env trong từng Application Package

9. Tạo monorepo mới nhanh

Starter bao gồm: 2 apps (web + docs) + các shared packages (ui, utils, config-eslint, config-ts).

Tài liệu tham khảo

Cập nhật lần cuối