TL;DR
- pnpm's
workspace:*is a local-only protocol - Publishing with
npm publishas-is makes the package unusable for others -
pnpm publishauto-replaces it, but requires proper setup - For simplicity, npm workspaces + normal version specifiers works fine
What Happened
I had a monorepo set up with pnpm, using workspace:* for inter-package dependencies.
// packages/react/package.json
{
"name": "@my-lib/react",
"dependencies": {
"@my-lib/core": "workspace:*"
}
}
Everything worked fine in local development, so I ran npm publish...
npm warn Invalid dependency "@my-lib/core": "workspace:*"
When someone tried to install the published package:
npm error Could not resolve dependency:
npm error peer workspace:* from @my-lib/react@0.1.0
Why This Happens
workspace:* is a local-only protocol used by pnpm/npm/yarn workspace features.
- Locally: "reference the package within this workspace"
- After publishing: unresolvable (npm registry doesn't understand
workspace:)
Solutions
Option 1: Use pnpm publish (requires setup)
pnpm can replace workspace:* with actual versions on publish.
workspace:* → *
workspace:^ → ^x.y.z
workspace:~ → ~x.y.z
However, this isn't enabled by default. You need proper configuration:
# pnpm-workspace.yaml
packages:
- 'packages/*'
And you must use pnpm publish (not npm publish).
Option 2: Manually write versions
Replace workspace:* with actual versions before publishing.
{
"dependencies": {
"@my-lib/core": "^1.2.3"
}
}
Tedious but reliable.
Option 3: Switch to npm workspaces (simplest)
Drop pnpm and use npm workspaces with normal version specifiers from the start.
// package.json (root)
{
"workspaces": [
"packages/*"
]
}
// packages/react/package.json
{
"dependencies": {
"@my-lib/core": "^1.2.3"
}
}
With npm workspaces, if a matching local package exists, it automatically symlinks. No special workspace:* notation needed.
pnpm and npm Publish to the Same Place
An easy point to misunderstand: both pnpm publish and npm publish go to the same npm registry.
Package managers are just client tools — the publish destination is shared. So:
- Packages published with pnpm can be installed with npm
- Packages published with npm can be installed with pnpm
- Same goes for yarn
Conclusion
| Approach | Pros | Cons |
|---|---|---|
pnpm + workspace:* + pnpm publish
|
Local dev is easy | Complex setup, accidents with npm publish
|
| pnpm + manual version specifiers | Reliable | Version updates are tedious |
| npm workspaces + normal versions | Simple, fewer accidents | Lacks pnpm's speed |
For small monorepos, npm workspaces is probably enough. If you need pnpm's fast installs for a large project, you'll need to properly set up the pnpm publish workflow.
Hope this helps someone.
Top comments (0)