Why Lerna Needs Modern (Nx-Powered) Rules
Lerna was the original JavaScript monorepo tool — and it nearly died. Nrwl (the Nx company) took over maintenance and rebuilt Lerna on top of Nx. Modern Lerna (v6+) delegates task running to Nx while keeping Lerna's strengths: versioning and publishing npm packages. AI generates Lerna 4 patterns: lerna bootstrap (deprecated), lerna run without Nx caching, and manual changelog management.
Modern Lerna is specifically for monorepos that publish npm packages. If you do not publish to npm, use Turborepo or Nx instead — Lerna's value is its versioning and publishing workflow. AI reaches for Lerna for any monorepo, not understanding that Lerna is the right tool only when npm publishing is a core requirement.
These rules target Lerna 8+ with Nx integration. They cover versioning strategies, conventional commits, publishing, changelog generation, and CI configuration.
Rule 1: Lerna with Nx — Not Legacy Lerna
The rule: 'Lerna 8 uses Nx for task running: lerna run build uses Nx under the hood with caching and dependency-aware scheduling. Configure in nx.json (not lerna.json) for: task pipelines, caching, and remote cache. lerna.json configures: versioning strategy, changelog preset, and publishing options. Never use lerna bootstrap — it is removed. Use your package manager workspaces (npm, pnpm, yarn) for dependency installation.'
For task running: 'lerna run build runs build across all packages — Nx handles: parallel execution, dependency ordering, and output caching. Configure in lerna.json: { "$schema": "...", "version": "independent", "npmClient": "pnpm", "command": { "version": { "conventionalCommits": true } } }. Nx caches task outputs — subsequent runs of unchanged packages skip entirely.'
AI generates lerna bootstrap, lerna link, and lerna add — all deprecated or removed in modern Lerna. pnpm/npm/yarn workspaces handle dependency installation. Lerna handles versioning and publishing. Nx handles task running and caching.
- lerna run uses Nx — caching, parallel, dependency-aware scheduling
- nx.json for task config — lerna.json for versioning and publishing
- No lerna bootstrap — package manager workspaces handle deps
- No lerna link, lerna add — use pnpm add/npm install directly
- Lerna = versioning + publishing. Nx = task running + caching.
lerna bootstrap, lerna link, and lerna add are all deprecated or removed. Package manager workspaces (pnpm/npm/yarn) handle dependency installation. Lerna handles versioning and publishing. AI generates the deprecated commands from old training data.
Rule 2: Versioning Strategies — Fixed vs Independent
The rule: 'Choose one versioning strategy: Fixed (all packages share one version — lerna.json: "version": "1.0.0") or Independent (each package has its own version — lerna.json: "version": "independent"). Fixed is simpler: one version number, all packages release together. Independent is flexible: only changed packages get new versions.'
For fixed: 'All packages share the version in lerna.json. lerna version bumps all packages to the same version. Use for: component libraries, design systems, and related packages that should always be used together. Consumers install one version and know all packages are compatible.'
For independent: 'Each package has its own version in its package.json. lerna version only bumps packages that changed (or depend on changed packages). Use for: utility libraries, plugins, and packages used independently. Consumers can update one package without touching others.'
Rule 3: Conventional Commits for Automated Versioning
The rule: 'Use conventional commits for automated version bumping and changelog generation: feat: → minor version bump, fix: → patch bump, BREAKING CHANGE: → major bump. Configure: { "command": { "version": { "conventionalCommits": true, "message": "chore(release): publish" } } }. lerna version reads commit messages since the last release and determines the correct version bump automatically.'
For commit format: 'type(scope): description — feat(ui): add Button component, fix(api): handle null response, docs(readme): update installation. Types: feat (minor), fix (patch), perf (patch), docs (no bump), chore (no bump), refactor (no bump). Breaking changes: footer BREAKING CHANGE: or ! after type: feat!: remove deprecated API.'
For changelogs: 'Lerna generates CHANGELOG.md per package automatically from conventional commits. Each version entry lists: features, fixes, and breaking changes with links to commits. Never write changelogs manually — conventional commits automate the entire process. Review the generated changelog before publishing.',
- feat: → minor, fix: → patch, BREAKING CHANGE: → major — automated
- conventionalCommits: true in lerna.json — reads commits since last release
- CHANGELOG.md generated per package — features, fixes, breaking changes
- Never manual changelogs — commit messages ARE the changelog source
- Commit lint (commitlint) in CI — reject non-conventional commits
With conventional commits, lerna version reads your commit messages and generates CHANGELOG.md automatically. feat: → listed as a feature, fix: → listed as a fix. Never write changelogs manually — your commits are the source.
Rule 4: Publishing Workflow
The rule: 'Use the two-step publishing workflow: 1) lerna version — bumps versions, updates changelogs, creates git tags, pushes to git. 2) lerna publish from-git — publishes tagged packages to npm. Separate version from publish so you can: review the version bump before publishing, CI can publish from tags, and failed publishes can be retried without re-versioning.'
For CI publishing: 'Automate in CI: on git tag push (created by lerna version), run lerna publish from-git --yes. Set NPM_TOKEN as a CI secret. Use --no-verify-access to skip npm access check (faster in CI). Use --dist-tag next for pre-release publishes. Use lerna publish from-package if tags are lost (compares package.json versions to npm registry).'
For prepublish checks: 'lerna version runs prepublish checks: builds all packages (ensure they compile), runs tests (ensure they pass), verifies git is clean (no uncommitted changes). Configure in lerna.json: { "command": { "publish": { "preVersionCommand": "pnpm -r build && pnpm -r test" } } }. Never publish without building and testing first.'
Rule 5: When Lerna vs Turborepo vs Nx
The rule: 'Use Lerna when: your monorepo publishes npm packages and you need automated versioning + changelogs + publishing. Use Turborepo when: your monorepo has apps and internal packages but does not publish to npm. Use Nx when: you need generators, project graph analysis, and module boundary enforcement alongside build orchestration.'
For combining: 'Lerna + Nx is the official combination: Nx handles task running and caching, Lerna handles versioning and publishing. Lerna + Turborepo is possible but not officially supported — Turborepo and Nx overlap in task running. Choose one: Lerna+Nx or standalone Turborepo or standalone Nx.'
AI reaches for Lerna for any monorepo — even those that never publish to npm. If you are building apps (websites, APIs, internal tools) and not publishing packages, Lerna adds complexity without value. Use Turborepo or Nx for non-publishing monorepos.
- Lerna: npm publishing + versioning + changelogs — the publishing tool
- Turborepo: task caching + pipeline — the build orchestrator (no publishing)
- Nx: generators + project graph + module boundaries — the full IDE (optional publishing)
- Lerna + Nx: official combo — Nx for tasks, Lerna for publishing
- Never Lerna for non-publishing monorepos — use Turborepo or Nx instead
If your monorepo never publishes to npm, Lerna adds complexity without value. Turborepo (build orchestration) or Nx (full monorepo IDE) are better choices for non-publishing monorepos. Lerna is specifically for npm publishing workflows.
Complete Lerna Rules Template
Consolidated rules for Lerna 8+ monorepo projects.
- Lerna 8 with Nx: lerna run uses Nx caching — nx.json for tasks, lerna.json for versioning
- No lerna bootstrap — package manager workspaces for dependency installation
- Fixed versioning for coupled packages — independent for standalone packages
- Conventional commits: feat→minor, fix→patch, BREAKING CHANGE→major — automated
- Two-step publish: lerna version (bump + tag + push) → lerna publish from-git (npm)
- CHANGELOG.md auto-generated from commits — never manual changelogs
- CI: publish on tag push — NPM_TOKEN secret — --dist-tag next for pre-releases
- Lerna for publishing monorepos only — Turborepo/Nx for non-publishing monorepos