Monorepo Setup
Configure Better PM for optimal monorepo workflows with pnpm, bun, or npm workspaces
Better PM is designed from the ground up for monorepo environments. It automatically detects your workspace structure and prevents common mistakes like accidentally installing all packages when you meant to install just one.
How Better PM Detects Monorepos
Better PM uses lockfile detection to identify your package manager and workspace root. It searches upward from your current directory to find:
pnpm-lock.yamlfor pnpm workspacesbun.lockorbun.lockbfor bun workspacespackage-lock.jsonfor npm workspaces
Once the lockfile is found, Better PM determines the monorepo root and checks for workspace configuration.
Supported Workspace Configurations
pnpm
Better PM reads your pnpm-workspace.yaml file to discover workspace packages:
packages:
- 'apps/*'
- 'packages/*'
The CLI parses this file line-by-line to extract glob patterns, then enumerates all matching packages.
bun
Bun workspaces are configured in package.json:
{
"workspaces": ["apps/*", "packages/*"]
}
Or using the object syntax:
{
"workspaces": {
"packages": ["apps/*", "packages/*"]
}
}
Both formats are supported and automatically detected.
npm
npm workspaces use the same package.json format as bun:
{
"workspaces": ["apps/*", "packages/*"]
}
Better PM automatically uses the correct flags (-w) for npm workspace operations.
Context-Aware Installation
Better PM changes behavior based on where you run commands:
Inside a workspace package
When you run pm i from within a workspace package directory, Better PM automatically scopes the install to that package only:
cd apps/web
pm i # Only installs apps/web and its dependenciesHow it works:
- Searches upward for the nearest
package.json - Compares its directory with the lockfile directory
- If they differ and the package is within the monorepo, applies a filter
- For pnpm: uses
-F @myapp/web...(includes transitive workspace deps) - For bun/npm: resolves all workspace dependencies recursively
At the monorepo root
Running pm i at the root shows a warning and lists all workspace packages:
cd ~/my-monorepo
pm iOutput:
[WARNING] You are at the monorepo root. This will install ALL packages.
Workspace packages:
├── apps/
│ └── web "@myapp/web"
└── packages/
├── core "@myapp/core"
└── utils "@myapp/utils"
To install a specific package:
pm i -F <package-name>
To install everything:
pm i --sureIn non-interactive environments (like CI), use -y or --sure to bypass the prompt.
Targeted Package Installation
Install specific workspace packages from anywhere in your monorepo:
pm i -F @myapp/webpm i -F @myapp/web -F @myapp/apipm i -y # or --sureThe -F flag (alias for --filter) works consistently across all package managers:
- pnpm: maps to
pnpm -F <pkg> install - bun: maps to
bun install --filter <pkg> - npm: maps to
npm install -w <pkg>
Workspace Navigation
Quickly navigate between workspace packages using pm cd:
# Jump to a specific package
pm cd @myapp/web
# Return to monorepo root
pm cd
# List all workspace packages
pm pls
Example Monorepo Workflow
Here’s a complete example of working with a typical monorepo:
Navigate to your project
cd ~/code/my-monorepo
pm pls # List all packagesOutput:
├── apps/
│ ├── web "@myapp/web"
│ └── api "@myapp/api"
└── packages/
├── ui "@myapp/ui"
└── shared "@myapp/shared"Work on a specific package
pm cd @myapp/web
pm add react-query
pm i # Installs only @myapp/web (scoped automatically)Install multiple packages
# From monorepo root or any subdirectory:
pm i -F @myapp/web -F @myapp/apiAdd dependencies across packages
pm cd @myapp/api
pm add fastify @myapp/shared # Works with workspace deps tooBest Practices
Always use pm i from package directories
When working within a package, let Better PM automatically scope your installs:
Good:
cd apps/web
pm iAvoid:
cd ~/my-monorepo
pm i -F @myapp/web # Works, but more typingUse -y in CI environments
Continuous integration should never prompt interactively:
- name: Install dependencies
run: pm i -yThe -y flag (alias for --sure) confirms root-level installs without prompting.
Leverage workspace dependency resolution
Better PM automatically includes workspace dependencies when installing:
If @myapp/web depends on @myapp/ui, running pm i from apps/web/ will install both packages.
For pnpm, this uses the ... suffix: -F @myapp/web...
For bun/npm, dependencies are resolved recursively via collectWorkspaceDependencies.
Organize packages by type
Structure your workspace for clarity:
my-monorepo/
├── apps/ # Deployable applications
│ ├── web/
│ └── api/
├── packages/ # Shared libraries
│ ├── ui/
│ └── utils/
└── tools/ # Build tools, scripts
└── eslint-config/This makes pm pls output more readable and helps with workspace organization.
Common Issues
Advanced Configuration
Filter Patterns
Better PM passes filter values directly to your package manager, so you can use their native patterns:
# pnpm patterns
pm i -F "@myapp/*" # All packages in @myapp scope
pm i -F "./apps/*" # All packages in apps/ directory
# Multiple patterns
pm i -F "@myapp/web" -F "@myapp/api"
Package Manager Detection Order
Lockfiles are checked in this priority:
pnpm-lock.yaml→ pnpmbun.lock→ bunbun.lockb→ bunpackage-lock.json→ npm
If multiple lockfiles exist (not recommended), the first match wins.
Workspace Dependency Resolution
For bun and npm, Better PM recursively resolves workspace dependencies by:
- Reading all workspace package
package.jsonfiles - Building a dependency graph of workspace packages
- Including all transitive workspace dependencies in the filter
This ensures that installing one package also installs its workspace dependencies.