Managing Monorepo Dependencies with pnpm Workspaces
Learn how to implement pnpm Workspaces to eliminate dependency duplication and manage local package linking in monorepos using a content-addressable store.
11 Aug 2025, 06:25 UTC

The Challenge of Monorepo Dependency Bloat
Managing multiple packages in a single repository often leads to two primary problems: massive disk usage due to duplicated dependencies across packages and "phantom dependencies," where code accidentally relies on a package that is hoisted to the root but not explicitly listed in the local package.json.
pnpm solves this by using a content-addressable store. Instead of duplicating files, pnpm stores one copy of a dependency version globally and creates hard links to it in your project's node_modules. In a workspace environment, this allows you to share dependencies across dozens of packages without wasting disk space or risking unstable dependency resolution.
Prerequisites
- pnpm installed (v7.0.0 or later recommended)
- Node.js environment configured
- A root directory containing multiple sub-packages (e.g.,
/packages/ui,/packages/api)
Defining the Workspace Structure
To initialize a workspace, you must create a pnpm-workspace.yaml file in the root of your repository. This file tells pnpm exactly which directories contain the packages that should be linked together.
# pnpm-workspace.yaml
packages:
- 'packages/*' # All packages in the packages directory
- 'apps/*' # All applications in the apps directory
- '!**/test/**' # Exclude test directories from being treated as packages
Linking Local Packages
When one package in your workspace depends on another (e.g., your web-app depends on your shared-utils), you should link them using the --workspace flag. This ensures pnpm links to the local source code rather than attempting to download the package from a remote registry.
Run the following command from the root directory:
# Syntax: pnpm add <package-name> --filter <consumer-package> --workspace
# Example: Adding 'shared-utils' to 'web-app'
pnpm add shared-utils --filter web-app --workspace
Permissions: Standard user permissions are required. No sudo/administrator privileges are needed for these operations.
Risk: If you omit the --workspace flag and the package exists on npm, pnpm may install the remote version, leading to "out-of-sync" bugs where local changes aren't reflected in the consuming app.
Executing Commands Across the Workspace
Running scripts (like build or test) individually in every folder is inefficient. Use the recursive flag -r to execute a command across all defined packages.
| Goal | Command | Effect |
|---|---|---|
| Build everything | pnpm -r run build |
Runs the 'build' script in every package. |
| Targeted Build | pnpm --filter api run build |
Builds only the 'api' package. |
| Build Dependents | pnpm --filter api... run build |
Builds 'api' and everything that depends on it. |
Verification and Diagnostics
To verify that the workspace is functioning correctly, perform these checks:
- Symlink Check: Navigate to
packages/web-app/node_modules/shared-utils. On macOS/Linux, runls -la. You should see a symlink pointing back to the localpackages/shared-utilsdirectory rather than a physical folder of files. - Store Verification: Run
pnpm store statusto ensure the content-addressable store is intact and not corrupted. - Dependency Isolation: Attempt to import a package in your code that is installed in the root but not listed in the local
package.json. pnpm's strict resolution should cause this import to fail, confirming that phantom dependencies are blocked.
Limitations and Rollback
Some legacy build tools or older versions of Webpack may struggle with symlinks. If a tool cannot resolve the "real path" of a dependency, you may need to configure the tool's preserveSymlinks option to false.
Rollback: If the workspace configuration causes resolution errors, remove the pnpm-workspace.yaml file and delete the node_modules folders in the root and sub-packages. Run pnpm install within individual package directories to return to a standard, non-workspace installation.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.