Pulled ALL skills from 15 source repositories: - anthropics/skills: 16 (docs, design, MCP, testing) - obra/superpowers: 14 (TDD, debugging, agents, planning) - coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth) - better-auth/skills: 5 (auth patterns) - vercel-labs/agent-skills: 5 (React, design, Vercel) - antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo) - Plus 13 individual skills from various repos Mosaic Stack is not limited to coding — the Orchestrator and subagents serve coding, business, design, marketing, writing, logistics, analysis, and more. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
125 lines
2.5 KiB
Markdown
125 lines
2.5 KiB
Markdown
---
|
|
name: monorepo
|
|
description: Monorepo setup with pnpm workspaces, centralized aliases, and Turborepo. Use when creating or managing multi-package repositories.
|
|
---
|
|
|
|
# Monorepo Setup
|
|
|
|
## pnpm Workspaces
|
|
|
|
Use pnpm workspaces for monorepo management:
|
|
|
|
```yaml
|
|
# pnpm-workspace.yaml
|
|
packages:
|
|
- 'packages/*'
|
|
```
|
|
|
|
## Scripts Convention
|
|
|
|
Have scripts in each package, and use `-r` (recursive) flag at root,
|
|
Enable ESLint cache for faster linting in monorepos.
|
|
|
|
```json
|
|
// root package.json
|
|
{
|
|
"scripts": {
|
|
"build": "pnpm run -r build",
|
|
"test": "vitest",
|
|
"lint": "eslint . --cache --concurrency=auto"
|
|
}
|
|
}
|
|
```
|
|
|
|
In each package's `package.json`, add the scripts.
|
|
|
|
```json
|
|
// packages/*/package.json
|
|
{
|
|
"scripts": {
|
|
"build": "tsdown",
|
|
"prepack": "pnpm build"
|
|
}
|
|
}
|
|
```
|
|
|
|
## ESLint Cache
|
|
|
|
|
|
```json
|
|
{
|
|
"scripts": {
|
|
"lint": "eslint . --cache --concurrency=auto"
|
|
}
|
|
}
|
|
```
|
|
|
|
## Turborepo (Optional)
|
|
|
|
For monorepos with many packages or long build times, use Turborepo for task orchestration and caching.
|
|
|
|
See the dedicated Turborepo skill for detailed configuration.
|
|
|
|
## Centralized Alias
|
|
|
|
For better DX across Vite, Nuxt, Vitest configs, create a centralized `alias.ts` at project root:
|
|
|
|
```ts
|
|
// alias.ts
|
|
import fs from 'node:fs'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { join, relative } from 'pathe'
|
|
|
|
const root = fileURLToPath(new URL('.', import.meta.url))
|
|
const r = (path: string) => fileURLToPath(new URL(`./packages/${path}`, import.meta.url))
|
|
|
|
export const alias = {
|
|
'@myorg/core': r('core/src/index.ts'),
|
|
'@myorg/utils': r('utils/src/index.ts'),
|
|
'@myorg/ui': r('ui/src/index.ts'),
|
|
// Add more aliases as needed
|
|
}
|
|
|
|
// Auto-update tsconfig.alias.json paths
|
|
const raw = fs.readFileSync(join(root, 'tsconfig.alias.json'), 'utf-8').trim()
|
|
const tsconfig = JSON.parse(raw)
|
|
tsconfig.compilerOptions.paths = Object.fromEntries(
|
|
Object.entries(alias).map(([key, value]) => [key, [`./${relative(root, value)}`]]),
|
|
)
|
|
const newRaw = JSON.stringify(tsconfig, null, 2)
|
|
if (newRaw !== raw)
|
|
fs.writeFileSync(join(root, 'tsconfig.alias.json'), `${newRaw}\n`, 'utf-8')
|
|
```
|
|
|
|
Then update the `tsconfig.json` to use the alias file:
|
|
|
|
```json
|
|
{
|
|
"extends": [
|
|
"./tsconfig.alias.json"
|
|
]
|
|
}
|
|
```
|
|
|
|
### Using Alias in Configs
|
|
|
|
Reference the centralized alias in all config files:
|
|
|
|
```ts
|
|
// vite.config.ts
|
|
import { alias } from './alias'
|
|
|
|
export default defineConfig({
|
|
resolve: { alias },
|
|
})
|
|
```
|
|
|
|
```ts
|
|
// nuxt.config.ts
|
|
import { alias } from './alias'
|
|
|
|
export default defineNuxtConfig({
|
|
alias,
|
|
})
|
|
```
|