monorepo-management
Skill8 starsChanged 10 days agoMITView on GitHub
Sets up and maintains monorepos - workspace tooling choice, package boundaries, affected-only builds and tests, remote caching, shared config, versioning and code ownership. Use when creating or restructuring a monorepo, adding a package or app to one, CI is slow because everything rebuilds, imports cross package boundaries, or choosing between Nx, Turborepo, Bazel, pnpm, Gradle, Go or Cargo workspaces. Not for splitting a monolith into services.
7 other projects use a version of this.
Adopted by
Most recently taken up by
- nisarth/claude-skills-storetheir own version, first seen Nov 8, 2026
- xfstudio/skillstheir own version, first seen Oct 13, 2026
- Samueladewole/claude-skillstheir own version, first seen Oct 13, 2026
- gluestack/gluestack-uitheir own version, first seen Oct 8, 2026
- ai4brands-design/claude-skillstheir own version, first seen Mar 22, 2026
- CodeWithBehnam/cc-docstheir own version, first seen Mar 15, 2026
Other versions7 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 7
- gluestack/gluestack-ui★ 5.3ksame name
- xfstudio/skills★ 9same name
- ai4brands-design/claude-skills★ 2same name
- CodeWithBehnam/cc-docs★ 2same name
- nisarth/claude-skills-store★ 1same name
- dhriyatinandu-bot/claude-skills★ 0same name
- Samueladewole/claude-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository60 other files it gives its agents.
- api-designSkill
- auth-implementationSkill
- background-jobsSkill
- building-agentsSkill
- caching-strategiesSkill
- ci-cd-pipelinesSkill
- cloud-cost-optimizationSkill
- codebase-onboardingSkill
- code-review-changesSkill
- concurrency-patternsSkill
- database-migrationsSkill
- database-schema-designSkill
- database-testingSkill
- data-pipelinesSkill
- data-privacy-retentionSkill
- dependency-upgradesSkill
- design-docsSkill
- design-systemsSkill
- dockerfilesSkill
- domain-driven-designSkill
- event-driven-architectureSkill
- file-storage-uploadsSkill
- frontend-securitySkill
- git-workflowSkill
- graphql-apisSkill
- grpc-servicesSkill
- incident-responseSkill
- infrastructure-as-codeSkill
- internationalizationSkill
- kubernetes-deploymentsSkill
- large-scale-migrationsSkill
- legacy-refactoringSkill
- llm-evalsSkill
- llm-integrationSkill
- mcp-serversSkill
- micro-frontendsSkill
- ml-experimentsSkill
- nosql-designSkill
- observabilitySkill
- orm-patternsSkill
- performance-profilingSkill
- postgres-operationsSkill
- rag-systemsSkill
- react-patternsSkill
- realtime-apisSkill
- resilience-patternsSkill
- root-cause-debuggingSkill
- search-integrationSkill
- security-auditSkill
- seo-and-ssrSkill
- sql-optimizationSkill
- system-designSkill
- test-strategySkill
- threat-modelingSkill
- typescript-patternsSkill
- unit-testingSkill
- verify-before-doneSkill
- web-accessibilitySkill
- web-performanceSkill
- writing-skillsSkill
The file
We split this skill into the rules it gives an agent
10 rules. 0 are common, 8 are distinctive, and 2 are very specific to this project.
0
Common
Most of the 7 edited versions we read keep these.
8
Distinctive
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 19
Not for: breaking a monolith into deployable services (see the large-scale-migrations skill).
- Distinctive: line 31
If most answers are on the right, keep separate repos and share code through versioned packages.
- Distinctive: line 35
Start with the lightest tool that gives you affected builds and caching for your stack.
- Distinctive: line 60
One lockfile at the root: Commit it. Never commit per-package lockfiles in a JS workspace.
- Distinctive: line 98
Prefer "no versions" for internal packages: it is the main benefit of a monorepo.
- Very specific: line 102
Add a CODEOWNERS file (GitHub: root, docs/ or .github/.
- Distinctive: line 103
Every package has an owner and a short README: purpose, public API, how to test.
- Distinctive: line 104
Keep root-level files (CI, lockfile, shared config) owned by the platform/tooling owners.
- Distinctive: line 109
Deep imports into other packages: - every internal refactor becomes a cross-team breaking change.
- Very specific: line 122
Every package has an owner in CODEOWNERS and a README.
“Common” is measured: kept by at least 6 in 10 of the 7 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Monorepo Management
A monorepo only works if two things stay true: package boundaries are enforced by tooling, and CI does work proportional to the change, not to the repo. Without both, a monorepo becomes a slow, tangled monolith with extra config.
When to use
- Creating a monorepo, or moving several repos into one.
- Adding a new app or package to an existing workspace.
- CI time grows with repo size; every PR rebuilds and retests everything.
- Packages import each other's internals; changes in one break others unexpectedly.
- Choosing or replacing workspace tooling.
Not for: breaking a monolith into deployable services (see the large-scale-migrations skill). A monorepo is about where code lives, not how it is deployed.
Does a monorepo fit?
| Signal | Monorepo helps | Monorepo hurts |
| Shared code | Many packages share libraries, types, config | Projects share little |
| Change shape | Changes often span several packages (API + client) | Changes stay inside one project |
| Teams | Teams accept shared tooling and conventions | Teams need different toolchains, release cadences, access controls |
| Tooling budget | Someone owns build/CI tooling | Nobody has time to maintain the build system |
| Access control | Code can be visible to all contributors | Parts must be hidden from some contributors |
If most answers are on the right, keep separate repos and share code through versioned packages.
Choosing tooling
Start with the lightest tool that gives you affected builds and caching for your stack. Add a heavier one only when you hit its limits.
| Tool | Best for | Affected / caching | Cost |
| npm / pnpm / yarn workspaces | JS/TS, linking local packages | None by themselves (pnpm --filter can select changed packages) | Lowest |
| Turborepo | JS/TS task orchestration on top of workspaces | Content-hash task cache, local and remote; filter by git range | Low |
| Nx | JS/TS (plus plugins for other stacks), larger orgs | Project graph, nx affected, local and remote cache, boundary lint rules | Medium |
| Bazel | Polyglot, very large repos, hermetic builds | Fine-grained, remote cache and remote execution | High: needs dedicated owners |
| Gradle multi-project | JVM | Incremental builds, build cache (local/remote) | Medium |
Go workspaces (go.work) | Several Go modules developed together | Go build cache; no affected detection | Low |
| Cargo workspaces | Rust crates | Shared target/ and Cargo.lock; incremental compilation | Low |
.NET solution (*.sln) + Directory.Build.props | .NET | Incremental builds; shared props and central package management | Low |
Defaults: JS/TS with fewer than ~50 packages: pnpm workspaces + Turborepo or Nx. JVM: Gradle. Polyglot at large scale with a platform team: Bazel.
Workflow: structure the repo
- Pick a layout and stick to it.
apps/ # deployable things: web, api, workers packages/ # libraries consumed by apps (or libs/) tooling/ # shared config: eslint, tsconfig, build scripts - Declare the workspace in the tool's root file:
pnpm-workspace.yaml(packages:globs),"workspaces"in rootpackage.json(npm/yarn),settings.gradle(.kts)include(...),go.work(go work init,go work use ./svc),[workspace] membersin rootCargo.toml. - Use workspace references for internal deps, not published versions:
"@acme/ui": "workspace:*"(pnpm, Yarn 2+; npm and Yarn 1 use a plain version range),implementation(project(":lib"))(Gradle),path = "../lib"orworkspace = true(Cargo). - One lockfile at the root. Commit it. Never commit per-package lockfiles in a JS workspace.
- Centralize versions of third-party deps where the tool supports it: Cargo
[workspace.dependencies], Gradle version catalogs (gradle/libs.versions.toml), .NET Central Package Management (Directory.Packages.props), pnpm catalogs (check that the installed pnpm version supports them). One version of each dependency across the repo prevents "works in package A, breaks in B". - Share config through packages:
tooling/tsconfigwithtsconfig.base.json, an ESLint config package, a shared Gradle convention plugin. Packages extend; they do not copy.
Boundaries
Rules every repo needs, enforced by a tool that fails CI:
- Import packages only through their public entry point. No
@acme/ui/src/internal/button. Set"exports"in eachpackage.jsonso deep imports fail at resolution. - Dependency direction is one way. Apps depend on packages; packages never depend on apps; low-level packages never depend on feature packages.
- No cycles between packages.
| Stack | Enforcement |
| JS/TS | package.json exports; Nx @nx/enforce-module-boundaries with project tags; eslint-plugin-boundaries; dependency-cruiser; ESLint no-restricted-imports |
| JVM | Gradle project dependencies (no dependency means no access); ArchUnit tests for package rules |
| Go | internal/ directories are enforced by the compiler |
| Bazel | visibility attributes on targets |
| .NET | Project references; internal + InternalsVisibleTo only for tests |
CI: work proportional to the change
- Compute affected projects from the diff against the merge base:
nx affected -t lint test build,turbo run test --filter=...[origin/main],pnpm --filter "...[origin/main]" test. Newer Turborepo versions also offer--affected; checkturbo run --help. - Fetch enough history for the diff: with GitHub Actions
actions/checkout, setfetch-depth: 0(or fetch the base branch) or affected detection silently falls back to "everything" or "nothing". - Include dependents, not just changed packages. A change to
packages/uimust test every app that uses it. Turborepo/pnpm filter syntax...pkgselects dependents;nx affecteddoes this by default. - Cache task outputs keyed by inputs (sources, lockfile, env vars, tool versions). Declare outputs (
dist/**,build/) and inputs precisely; a missing input gives wrong cache hits, which is worse than no cache. - Turn on remote caching so CI and developers share results (Nx and Turborepo offer hosted and self-hosted options; Gradle and Bazel support remote cache servers). Treat cache write access as sensitive: anyone who can write can poison builds. Let only CI on trusted branches write.
- Run a full build on main periodically (nightly or on merge) to catch anything affected detection missed.
- Shard large test suites across CI machines once affected-only is not enough.
Versioning and releasing
| Model | When | How |
| Single version (everything releases together) | Apps deployed together; internal-only packages | One version in root; tag the repo |
| Independent versions | Packages published to a registry for outside consumers | Changesets (npx changeset, then changeset version and changeset publish), Nx release, or similar |
| No versions (always head) | Internal packages consumed only inside the repo | workspace:*; apps deploy from a commit |
Prefer "no versions" for internal packages: it is the main benefit of a monorepo. Publishing to a registry is outward-facing: confirm with the user before running any publish command.
Ownership
- Add a
CODEOWNERSfile (GitHub: root,docs/or.github/; GitLab: root,docs/or.gitlab/) mapping paths to teams, and require code-owner review on protected branches. On Azure DevOps, use branch policies with path-filtered required reviewers. - Every package has an owner and a short README: purpose, public API, how to test.
- Keep root-level files (CI, lockfile, shared config) owned by the platform/tooling owners.
Anti-patterns
- Monorepo without affected builds - CI time grows forever and developers start skipping it.
- Deep imports into other packages - every internal refactor becomes a cross-team breaking change.
- Copy-pasted config - twenty slightly different
tsconfig.jsonfiles. Extend a shared base. - Multiple versions of the same dependency - subtle runtime bugs (two React copies, two protobuf runtimes). Centralize versions.
- Undeclared task inputs - caches return stale outputs; builds "pass" with old code.
- Shallow clones in CI - affected detection compares against nothing.
- Bazel without owners - adopting a heavyweight build system nobody can maintain.
Done when
- The workspace builds and tests from a clean clone with the documented root commands.
- Boundary rules run in CI and fail on a deep import or wrong-direction dependency.
- A PR touching one leaf package runs only that package and its dependents; a change to shared config runs everything.
- Task caching is on, with inputs and outputs declared; cache writes are limited to trusted CI.
- Every package has an owner in
CODEOWNERSand a README.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

