monorepo-management

Monorepo Management with PNPM

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "monorepo-management" with this command: npx skills add constructive-io/constructive-skills/constructive-io-constructive-skills-monorepo-management

Monorepo Management with PNPM

Best practices for managing large PNPM monorepos following Constructive conventions. Covers workspace configuration, dependency management, selective builds, and package organization.

When to Apply

Use this skill when:

  • Managing a multi-package repository

  • Configuring workspace dependencies

  • Setting up selective builds and filtering

  • Organizing packages in a large codebase

  • Configuring lerna versioning strategies

Workspace Configuration

pnpm-workspace.yaml

Define package locations:

packages:

  • 'packages/*'

For larger projects with multiple directories:

packages:

  • 'packages/*'
  • 'pgpm/*'
  • 'graphql/*'
  • 'postgres/*'
  • 'apps/*'
  • 'libs/*'

Root package.json

{ "name": "my-workspace", "version": "0.0.1", "private": true, "scripts": { "build": "pnpm -r run build", "test": "pnpm -r run test", "lint": "pnpm -r run lint", "clean": "pnpm -r run clean", "deps": "pnpm up -r -i -L" } }

Key points:

  • Root is always private: true

  • Scripts use pnpm -r for recursive execution

  • deps script for interactive dependency updates

Workspace Dependencies

workspace:* Protocol

Reference internal packages:

{ "dependencies": { "my-utils": "workspace:*" } }

When published, workspace:* is replaced with the actual version.

Dependency Types

Protocol Behavior

workspace:*

Latest version in workspace

workspace:^

Compatible version range

workspace:~

Patch version range

Adding Workspace Dependencies

Add workspace dependency

pnpm add my-utils --filter my-app --workspace

Add external dependency to specific package

pnpm add lodash --filter my-app

Add dev dependency to root

pnpm add -D typescript -w

Filtering and Selective Builds

--filter Flag

Run commands on specific packages:

Single package

pnpm --filter my-app run build

Multiple packages

pnpm --filter my-app --filter my-utils run build

Glob patterns

pnpm --filter "my-*" run build

Package and its dependencies

pnpm --filter my-app... run build

Package and its dependents

pnpm --filter ...my-utils run build

Exclude packages

pnpm --filter "!my-legacy" run build

Dependency-Aware Builds

Build package and all its dependencies

pnpm --filter my-app... run build

Build only dependencies (not the package itself)

pnpm --filter "my-app^..." run build

Build dependents (packages that depend on this)

pnpm --filter "...my-utils" run build

Changed Packages

Packages changed since main

pnpm --filter "...[origin/main]" run build

Packages changed in last commit

pnpm --filter "...[HEAD~1]" run build

Package Organization

Directory Structure

Organize by domain or type:

my-workspace/ ├── packages/ # Shared utilities │ ├── utils/ │ ├── types/ │ └── config/ ├── apps/ # Applications │ ├── web/ │ └── api/ ├── libs/ # Domain libraries │ ├── auth/ │ └── database/ ├── pgpm/ # PGPM modules (if hybrid) │ └── migrations/ ├── pnpm-workspace.yaml ├── lerna.json └── package.json

Naming Conventions

Type Convention Example

Scoped packages @org/package-name

@myorg/utils

Internal packages package-name

my-utils

Apps app-name

web-app

Lerna Configuration

Independent Versioning

Each package versioned separately:

{ "$schema": "node_modules/lerna/schemas/lerna-schema.json", "version": "independent", "npmClient": "pnpm", "command": { "publish": { "allowBranch": "main", "conventionalCommits": true } } }

Best for: utility libraries with different release cycles.

Fixed Versioning

All packages share same version:

{ "$schema": "node_modules/lerna/schemas/lerna-schema.json", "version": "1.0.0", "npmClient": "pnpm", "command": { "publish": { "allowBranch": "main", "conventionalCommits": true } } }

Best for: tightly coupled packages that release together.

Versioning Commands

Version changed packages

pnpm lerna version

Version with specific bump

pnpm lerna version patch pnpm lerna version minor pnpm lerna version major

Preview without changes

pnpm lerna version --no-git-tag-version --no-push

Dependency Management

Update Dependencies

Interactive update all packages

pnpm up -r -i -L

Update specific dependency everywhere

pnpm up lodash -r

Update to latest

pnpm up lodash@latest -r

Check for Outdated

pnpm outdated -r

Dedupe Dependencies

pnpm dedupe

Build Optimization

Parallel Builds

PNPM runs in parallel by default. Control concurrency:

Limit concurrent tasks

pnpm -r --workspace-concurrency=4 run build

Topological Order

Dependencies are built first automatically:

Builds in dependency order

pnpm -r run build

Caching

Use turbo or nx for build caching in large repos:

{ "scripts": { "build": "turbo run build" } }

CI/CD Patterns

Install Dependencies

pnpm install --frozen-lockfile

Build Changed Packages

Build packages changed since main

pnpm --filter "...[origin/main]" run build

Test Changed Packages

pnpm --filter "...[origin/main]" run test

Publish Workflow

Version and publish

pnpm lerna version --yes pnpm lerna publish from-package --yes

Common Commands Reference

Command Description

pnpm install

Install all dependencies

pnpm -r run build

Build all packages

pnpm -r run test

Test all packages

pnpm --filter <pkg> run <cmd>

Run command in specific package

pnpm --filter <pkg>... run <cmd>

Run in package and dependencies

pnpm add <dep> --filter <pkg>

Add dependency to package

pnpm add <dep> -w

Add dependency to root

pnpm up -r -i -L

Interactive dependency update

pnpm lerna version

Version packages

pnpm lerna publish

Publish packages

Hybrid Workspaces

Some repos (like Constructive) have both PNPM packages and PGPM modules:

pnpm-workspace.yaml

packages:

  • 'packages/*' # TypeScript packages
  • 'pgpm/*' # PGPM CLI and tools
  • 'postgres/*' # PostgreSQL utilities

The root may also have a pgpm.json for SQL module configuration.

Troubleshooting

Dependency Resolution Issues

Clear cache and reinstall

pnpm store prune rm -rf node_modules pnpm install

Workspace Link Issues

Check workspace links

pnpm why <package-name>

Build Order Issues

Verify dependency graph

pnpm list -r --depth=0

Best Practices

  • Keep root private: Never publish the root package

  • Use workspace protocol: Always workspace:* for internal deps

  • Consistent structure: Same directory layout across packages

  • Shared config: Extend root tsconfig.json, eslint.config.js

  • Filter in CI: Only build/test changed packages

  • Lock file: Always commit pnpm-lock.yaml

  • Dedupe regularly: Run pnpm dedupe periodically

  • Document dependencies: Clear README for each package

References

  • Related skill: pnpm-workspace for workspace setup

  • Related skill: pnpm-publishing for publishing workflow

  • Related skill: pgpm-workspace for SQL module workspaces

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

planning-blueprinting

No summary provided by upstream source.

Repository SourceNeeds Review
General

drizzle-orm

No summary provided by upstream source.

Repository SourceNeeds Review
General

pgsql-parser-testing

No summary provided by upstream source.

Repository SourceNeeds Review