Understanding npm link and Its Better Alternative in pnpm

If you’ve ever built multiple JavaScript packages that depend on each other, you’ve probably used — or at least heard of — npm link. It’s a handy tool that lets you work on a library and an app at the same time without constantly reinstalling or publishing updates.

But if you’ve switched to pnpm, you might wonder — where did my npm link go?
Good news: pnpm has better, faster, and more reliable ways to handle local linking.

Let’s dive in 👇


When you run npm link, npm creates a symbolic link (symlink) between a local package and another project.

Example structure:

/packages/ui
/app

With npm:

  1. Go into your local library:

     cd packages/ui
     npm link
    

    This registers the package globally.

  2. Then, inside your app:

     cd ../app
     npm link ui
    

    This tells npm to use your local version of ui instead of the one from the npm registry.

Result → Any changes you make inside /packages/ui reflect instantly in /app without reinstalling.


⚡ Why pnpm Is Different

pnpm was designed for speed, disk efficiency, and workspace management.
Instead of scattering node_modules everywhere, pnpm uses a content-addressable store and symlinks under the hood.

So naturally, pnpm gives us a few better ways to handle linking — depending on your setup.


If you have a monorepo, pnpm workspaces make linking automatic.

Example structure:

pnpm-workspace.yaml
packages/
  ui/
  app/

pnpm-workspace.yaml

packages:
  - "packages/*"

Then, in your app’s package.json, declare:

{
  "dependencies": {
    "ui": "workspace:*"
  }
}

Run:

pnpm install

✅ Done — pnpm automatically symlinks your local ui package into app/node_modules.

➡️ No need to manually link anything.
➡️ Every edit in /packages/ui is reflected instantly in /app.

This is the cleanest and most reliable way to work with local packages in pnpm.


If you’re working outside a monorepo, you can still manually link.

cd ~/projects/ui
pnpm link --global
cd ~/projects/app
pnpm link ui

This behaves just like npm link, but uses pnpm’s internal linking system.


🔗 Option 3 — Direct Local Linking

You can also directly link a local path without touching the global store:

pnpm link ../ui

This instantly symlinks your local folder into node_modules.

Useful for quick experiments or smaller projects.


🧠 Quick Comparison

Tasknpm commandpnpm equivalentNotes
Create global linknpm linkpnpm link --globalRegisters globally
Link to global packagenpm link pkg-namepnpm link pkg-nameSame behavior
Local direct linkpnpm link ../path/to/pkgFast and local
Monorepo linking (automatic)manual setup requiredworkspace:*Best practice

🧰 Handy Extras

List all global links:

pnpm link --global list

Remove a link:

pnpm unlink ui

🧭 Final Thoughts

While npm link served developers well for years, pnpm workspaces make local development between multiple packages smoother and more predictable.

If you’re maintaining multiple interdependent packages — say a design system and a frontend app — setting up a monorepo with pnpm workspaces will save you endless linking headaches.

Once you try it, you’ll never go back to manual linking again.