- Rename all references from hub-guide to code-guide - Remove project-specific hub-guide skill (100% Asepharyana Hub specific) - Genericize examples in monorepo, docker, ci-cd, engineering-principles skills - Use generic service names (frontend, api, worker instead of hub, scraper) - Use generic registry paths instead of ghcr.io/asepharyana/asepharyana-hub - Remove project-specific deployment and infrastructure references
4.8 KiB
4.8 KiB
name, description
| name | description |
|---|---|
| monorepo | Monorepo best practices — tooling, workspace configuration, shared dependencies, CI/CD, and dependency management. Use when working in monorepos (pnpm workspaces, moon, turborepo, Nx), managing shared packages. Triggers from project files and configuration, not just keyword matching." |
Monorepo Best Practices
Tool Selection
| Tool | Best For | Why |
|---|---|---|
| pnpm workspaces | Package management | Strict, fast, disk-efficient |
| moon | Monorepo orchestration | Task orchestration + caching |
| turborepo | Task orchestration | Simple caching, good for JS/TS |
| Nx | Full monorepo framework | Generators, dependency graph, affected commands |
| Git submodules | Multi-repo coordination | Separate repos imported together (this repo's pattern) |
Workspace Structure (pnpm + moon)
├── apps/
│ ├── app1/ # Application (submodule)
│ └── app2/ # Another application (submodule)
├── packages/ # Shared libraries (when not submodules)
├── infra/ # Shared infra config
├── pnpm-workspace.yaml
├── moon.yml
└── package.json
pnpm-workspace.yaml
packages:
- 'apps/*'
- 'packages/*'
moon.yml (root)
$schema: 'https://moonrepo.dev/schemas/project.json'
language: 'typescript'
type: 'application'
Shared Dependencies
# Install a shared dependency
pnpm add -w typescript
# Install in a specific package
pnpm add --filter @scope/package zod
# Run in all packages
pnpm -r run build
Rules:
- One version of a dependency across the monorepo — use
pnpm overridesorresolution. - Root
devDependenciesfor shared tooling (TypeScript, Biome, ESLint). - Explicit
dependencies— never rely on hoisting. - Lock file (
pnpm-lock.yaml) committed — immutable installs.
Git Submodules
my-monorepo/
├── apps/
│ ├── app1/ → org/app1-repo
│ └── app2/ → org/app2-repo
Submodule Workflow
# Init after clone
git submodule update --init --recursive
# Update all submodules to latest
git submodule foreach git pull origin main
# Update one submodule
cd apps/app1 && git checkout main && git pull
cd ../.. && git add apps/app1 && git commit -m "chore(deps): update app1 submodule"
git push
State indicators:
(HEAD)— detached at committed pointer (normal state).(main)— on a branch (you've donecd apps/name && git checkout main).- Dirty — uncommitted changes inside submodule.
When to Use Submodules vs Workspaces
| Need | Use |
|---|---|
| Independent repos, separate deploy | Submodules |
| Shared code within one repo | Workspaces |
| Tightly coupled, always deploy together | Workspaces |
| Loosely coupled, different teams | Submodules |
CI/CD for Monorepos
Selective Builds
# Only run relevant workflows based on changed paths
on:
push:
branches: [main]
paths:
- 'apps/app1/**'
- 'infra/docker/app1.Dockerfile'
Affected Commands (Nx/Turborepo/Moon)
moon ci # Runs affected tasks based on changes
npx nx affected:test # Nx style
turbo run build # Turborepo — leverages cache
Caching
- moon/turborepo cache task outputs by file hash + env.
- pnpm caches node_modules.
- Docker layer caching — Registry-based caching for Docker builds.
Shared Configuration
TypeScript
// tsconfig.base.json at root — extended by all packages
{
"compilerOptions": {
"strict": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"moduleResolution": "bundler"
}
}
ESLint / Biome
// biome.json at root — shared config for all packages
{
"formatter": { "indentStyle": "tab", "lineWidth": 120 },
"linter": { "rules": { "recommended": true } }
}
Dependency Management
- Dependabot / Renovate — automate dependency updates.
pnpm dedupe— deduplicate after updates.- Check for duplicates —
pnpm ls -rorpnpm why <package>. - When to upgrade:
- Patch: auto-merge.
- Minor: update weekly.
- Major: scheduled migration, document breaking changes.
Anti-patterns
- ❌ Different dependency versions across packages — inconsistent builds
- ❌ Hoisting assumptions — code works in dev but not in CI because of missing deps
- ❌ Monolithic
package.json— each package declares its own dependencies - ❌ No
.npmrcwithshamefully-hoist=true— defeats pnpm's strictness - ❌ Circular dependencies between packages — extract shared code
- ❌ Every change rebuilds everything — use affected commands and caching
- ❌ Submodule pointer drift — always commit after updating submodules