Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
914 changes: 914 additions & 0 deletions .agents/skills/turborepo/SKILL.md

Large diffs are not rendered by default.

70 changes: 70 additions & 0 deletions .agents/skills/turborepo/command/turborepo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
description: Load Turborepo skill for creating workflows, tasks, and pipelines in monorepos. Use when users ask to "create a workflow", "make a task", "generate a pipeline", or set up build orchestration.
---

Load the Turborepo skill and help with monorepo task orchestration: creating workflows, configuring tasks, setting up pipelines, and optimizing builds.

## Workflow

### Step 1: Load turborepo skill

```
skill({ name: 'turborepo' })
```

### Step 2: Identify task type from user request

Analyze $ARGUMENTS to determine:

- **Topic**: configuration, caching, filtering, environment, CI, or CLI
- **Task type**: new setup, debugging, optimization, or implementation

Use decision trees in SKILL.md to select the relevant reference files.

### Step 3: Read relevant reference files

Based on task type, read from `references/<topic>/`:

| Task | Files to Read |
| -------------------- | ------------------------------------------------------- |
| Configure turbo.json | `configuration/RULE.md` + `configuration/tasks.md` |
| Debug cache issues | `caching/gotchas.md` |
| Set up remote cache | `caching/remote-cache.md` |
| Filter packages | `filtering/RULE.md` + `filtering/patterns.md` |
| Environment problems | `environment/gotchas.md` + `environment/modes.md` |
| Set up CI | `ci/RULE.md` + `ci/github-actions.md` or `ci/vercel.md` |
| CLI usage | `cli/commands.md` |

### Step 4: Execute task

Apply Turborepo-specific patterns from references to complete the user's request.

**CRITICAL - When creating tasks/scripts/pipelines:**

1. **DO NOT create Root Tasks** - Always create package tasks
2. Add scripts to each relevant package's `package.json` (e.g., `apps/web/package.json`, `packages/ui/package.json`)
3. Register the task in root `turbo.json`
4. Root `package.json` only contains `turbo run <task>` - never actual task logic

**Other things to verify:**

- `outputs` defined for cacheable tasks
- `dependsOn` uses correct syntax (`^task` vs `task`)
- Environment variables in `env` key
- `.env` files in `inputs` if used
- Use `turbo run` (not `turbo`) in package.json and CI

### Step 5: Summarize

```
=== Turborepo Task Complete ===

Topic: <configuration|caching|filtering|environment|ci|cli>
Files referenced: <reference files consulted>

<brief summary of what was done>
```

<user-request>
$ARGUMENTS
</user-request>
241 changes: 241 additions & 0 deletions .agents/skills/turborepo/references/best-practices/RULE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
# Monorepo Best Practices

Essential patterns for structuring and maintaining a healthy Turborepo monorepo.

## Repository Structure

### Standard Layout

```
my-monorepo/
├── apps/ # Application packages (deployable)
│ ├── web/
│ ├── docs/
│ └── api/
├── packages/ # Library packages (shared code)
│ ├── ui/
│ ├── utils/
│ └── config-*/ # Shared configs (eslint, typescript, etc.)
├── package.json # Root package.json (minimal deps)
├── turbo.json # Turborepo configuration
├── pnpm-workspace.yaml # (pnpm) or workspaces in package.json
└── pnpm-lock.yaml # Lockfile (required)
```

### Key Principles

1. **`apps/` for deployables**: Next.js sites, APIs, CLIs - things that get deployed
2. **`packages/` for libraries**: Shared code consumed by apps or other packages
3. **One purpose per package**: Each package should do one thing well
4. **No nested packages**: Don't put packages inside packages

## Package Types

### Application Packages (`apps/`)

- **Deployable**: These are the "endpoints" of your package graph
- **Not installed by other packages**: Apps shouldn't be dependencies of other packages
- **No shared code**: If code needs sharing, extract to `packages/`

```json
// apps/web/package.json
{
"name": "web",
"private": true,
"dependencies": {
"@repo/ui": "workspace:*",
"next": "latest"
}
}
```

### Library Packages (`packages/`)

- **Shared code**: Utilities, components, configs
- **Namespaced names**: Use `@repo/` or `@yourorg/` prefix
- **Clear exports**: Define what the package exposes

```json
// packages/ui/package.json
{
"name": "@repo/ui",
"exports": {
"./button": "./src/button.tsx",
"./card": "./src/card.tsx"
}
}
```

## Package Compilation Strategies

### Just-in-Time (Simplest)

Export TypeScript directly; let the app's bundler compile it.

```json
{
"name": "@repo/ui",
"exports": {
"./button": "./src/button.tsx"
}
}
```

**Pros**: Zero build config, instant changes
**Cons**: Can't cache builds, requires app bundler support

### Compiled (Recommended for Libraries)

Package compiles itself with `tsc` or bundler.

```json
{
"name": "@repo/ui",
"exports": {
"./button": {
"types": "./src/button.tsx",
"default": "./dist/button.js"
}
},
"scripts": {
"build": "tsc"
}
}
```

**Pros**: Cacheable by Turborepo, works everywhere
**Cons**: More configuration

## Dependency Management

### Install Where Used

Install dependencies in the package that uses them, not the root.

```bash
# Good: Install in the package that needs it
pnpm add lodash --filter=@repo/utils

# Avoid: Installing everything at root
pnpm add lodash -w # Only for repo-level tools
```

### Root Dependencies

Only these belong in root `package.json`:

- `turbo` - The build system
- `husky`, `lint-staged` - Git hooks
- Repository-level tooling

### Internal Dependencies

Use workspace protocol for internal packages:

```json
// pnpm/bun
{ "@repo/ui": "workspace:*" }

// npm/yarn
{ "@repo/ui": "*" }
```

## Exports Best Practices

### Use `exports` Field (Not `main`)

```json
{
"exports": {
".": "./src/index.ts",
"./button": "./src/button.tsx",
"./utils": "./src/utils.ts"
}
}
```

### Avoid Barrel Files

Don't create `index.ts` files that re-export everything:

```typescript
// BAD: packages/ui/src/index.ts
export * from './button';
export * from './card';
export * from './modal';
// ... imports everything even if you need one thing

// GOOD: Direct exports in package.json
{
"exports": {
"./button": "./src/button.tsx",
"./card": "./src/card.tsx"
}
}
```

### Namespace Your Packages

```json
// Good
{ "name": "@repo/ui" }
{ "name": "@acme/utils" }

// Avoid (conflicts with npm registry)
{ "name": "ui" }
{ "name": "utils" }
```

## Common Anti-Patterns

### Accessing Files Across Package Boundaries

```typescript
// BAD: Reaching into another package
import { Button } from "../../packages/ui/src/button";

// GOOD: Install and import properly
import { Button } from "@repo/ui/button";
```

### Shared Code in Apps

```
// BAD
apps/
web/
shared/ # This should be a package!
utils.ts

// GOOD
packages/
utils/ # Proper shared package
src/utils.ts
```

### Too Many Root Dependencies

```json
// BAD: Root has app dependencies
{
"dependencies": {
"react": "^18",
"next": "^14",
"lodash": "^4"
}
}

// GOOD: Root only has repo tools
{
"devDependencies": {
"turbo": "latest",
"husky": "latest"
}
}
```

## See Also

- [structure.md](./structure.md) - Detailed repository structure patterns
- [packages.md](./packages.md) - Creating and managing internal packages
- [dependencies.md](./dependencies.md) - Dependency management strategies
Loading
Loading