pm link
Link local packages for development
Overview
The pm link command creates symbolic links between local packages, allowing you to develop and test packages together without publishing them.
Syntax
pm link [...args]
Arguments
args string[]
Arguments passed directly to your package manager’s link command
Examples
Create Global Link
In the package you want to link:
cd ~/projects/my-library
pm link
Running: pnpm link
This makes the package available globally for linking.
Link to Another Project
In the project that needs the package:
cd ~/projects/my-app
pm link my-library
Running: pnpm link my-library
Link with Path
Link directly using a file path:
pm link ../my-library
Running: pnpm link ../my-library
Use Cases
Local Development
Develop a library and application together:
Create Global Link
In your library project:
cd ~/projects/ui-library
pm linkLink in Application
In your application project:
cd ~/projects/web-app
pm link ui-libraryDevelop and Test
Changes in ui-library are immediately reflected in web-app
Testing Unpublished Changes
Test changes before publishing to npm:
# In library
cd ~/my-package
pm link
# In test project
cd ~/test-app
pm link my-package
# Make changes and test
# Changes are immediately available
Monorepo Alternative
While monorepos handle this automatically, pm link is useful for:
- Cross-monorepo development
- Testing packages outside their monorepo
- Temporary connections between projects
How It Works
From src/commands/link.ts:10-17:
export const linkCmd = cli.Command.make('link', { args: argsArg }, (args) =>
Effect.gen(function* () {
const pm = yield* PackageManagerService;
const passthrough = Array.from(args.args);
const cmd = ShellCommand.make(pm.name, 'link', ...passthrough);
yield* Console.log(`Running: ${pm.name} link ${passthrough.join(' ')}`);
yield* runShellCommand(cmd);
}).pipe(Effect.provide(PackageManagerLayer)),
);
The command:
- Detects your package manager
- Passes all arguments to the native link command
- Creates symbolic links in node_modules
Package Manager Behavior
# Create global link
pnpm link --global
# Link to package
pnpm link --global my-package
# Link with path
pnpm link ../my-package# Create global link
bun link
# Link to package
bun link my-package# Create global link
npm link
# Link to package
npm link my-packageVerification
Check if a package is linked:
pm ls my-package
my-app@1.0.0
└── my-package@1.0.0 -> /Users/you/projects/my-package
The -> indicates a symbolic link.
Troubleshooting
Link Not Working
If changes aren’t reflected:
-
Rebuild the linked package:
cd ~/my-package pm run build -
Check if link exists:
pm ls my-package -
Re-create the link:
pm unlink my-package pm link my-package
TypeScript Issues
For TypeScript projects, you may need:
{
"compilerOptions": {
"preserveSymlinks": true
}
}
Build Watch Mode
For real-time changes, run the linked package in watch mode:
cd ~/my-package
pm run build --watch
Best Practices
- Document links - Keep track of which packages are linked
- Use watch mode - Run builds in watch mode for instant updates
- Unlink after testing - Remove links when done to avoid confusion
- Consider alternatives - For monorepos, use workspace features instead
Related Commands
- pm unlink - Remove symbolic links
- pm ls - List dependencies and check links
- pm install - Install dependencies normally