npm link is a powerful tool for locally developing and testing npm packages. It allows developers to link local packages to other projects without publishing them.
Basic Concept of npm link
npm link creates two links:
- Global link: Links the local package to global node_modules
- Project link: Links the global link to the project's node_modules
Basic Usage
1. Linking a Local Package
Step 1: Create a global link in the package directory to be linked
bashcd /path/to/my-package npm link
This creates a symbolic link in the global node_modules pointing to the local package.
Step 2: Link in the project that will use the package
bashcd /path/to/my-project npm link my-package
This creates a symbolic link in the project's node_modules pointing to the global link.
2. Verify Links
bash# View global links npm list -g --depth=0 # View links in project npm list my-package # View detailed link information ls -la node_modules/my-package
Practical Use Cases
Use Case 1: Developing a Local Library
Suppose you're developing a utility library my-utils:
bash# 1. Enter the utility library directory cd ~/projects/my-utils # 2. Create a global link npm link # 3. Enter the project using the library cd ~/projects/my-app # 4. Link the utility library npm link my-utils # 5. Use in code import { formatDate } from 'my-utils';
Use Case 2: Developing a CLI Tool
npm link is particularly useful when developing command-line tools:
bash# 1. In the CLI tool directory cd ~/projects/my-cli # 2. Ensure package.json has the bin field { "name": "my-cli", "bin": { "my-cli": "./bin/cli.js" } } # 3. Create a global link npm link # 4. Now you can use it anywhere my-cli --help
Use Case 3: Developing a React Component Library
bash# 1. In the component library directory cd ~/projects/my-components # 2. Create a global link npm link # 3. Link in React application cd ~/projects/my-react-app npm link my-components # 4. Use components import { Button } from 'my-components';
Advanced Usage
1. Linking Scoped Packages
bash# Link scoped package cd ~/projects/@mycompany/my-package npm link # Link in project cd ~/projects/my-project npm link @mycompany/my-package
2. Linking Multiple Packages
bash# Link multiple local packages cd ~/projects/package-a npm link cd ~/projects/package-b npm link # Link all packages in project cd ~/projects/my-project npm link package-a package-b
3. Unlinking
bash# Unlink in project cd ~/projects/my-project npm unlink my-package # Unlink global cd ~/projects/my-package npm unlink -g # Or use unlink command npm unlink -g my-package
Common Issues
1. Link Not Taking Effect
Issue: Still using old version after linking
Solution:
bash# Clear cache npm cache clean --force # Re-link npm link # Restart development server npm run dev
2. TypeScript Type Errors
Issue: Linked package missing type definitions
Solution:
bash# Ensure package includes type definitions cd ~/projects/my-package npm run build # Re-link in project cd ~/projects/my-project npm unlink my-package npm link my-package
3. Dependency Conflicts
Issue: Linked package conflicts with project dependencies
Solution:
bash# Check dependencies npm ls my-package # Use npm link --force npm link my-package --force
4. Windows Symbolic Link Issues
Issue: Symbolic links on Windows require administrator privileges
Solution:
bash# Run terminal as administrator # Or enable developer mode # Settings -> Update & Security -> Developer mode
Best Practices
1. Use package.json Scripts
json{ "scripts": { "link": "npm link", "link:app": "npm link my-package", "unlink": "npm unlink -g my-package" } }
2. Document Linking Process
Explain how to link local packages in README:
markdown## Local Development To use this package locally without publishing: ```bash # In this package directory npm link # In your project directory npm link my-package
shell### 3. Use Watch Mode ```bash # Use watch mode in package directory cd ~/projects/my-package npm run watch # Code changes will automatically recompile
4. Test Linked Packages
bash# Test in project cd ~/projects/my-project npm test # Manual testing node -e "require('my-package').test()"
Integration with Other Tools
1. Integration with Yarn
bash# Yarn also supports link cd ~/projects/my-package yarn link cd ~/projects/my-project yarn link my-package
2. Integration with pnpm
bash# pnpm uses different linking mechanism cd ~/projects/my-package pnpm link --global cd ~/projects/my-project pnpm link --global my-package
3. Integration with Monorepo
bash# Use workspaces instead of npm link cd ~/projects/my-monorepo npm install # Workspaces automatically handle internal dependencies
Practical Example
Developing a Utility Function Library
my-utils/package.json:
json{ "name": "my-utils", "version": "1.0.0", "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { "build": "tsc", "watch": "tsc --watch" } }
my-utils/src/index.ts:
typescriptexport function formatDate(date: Date): string { return date.toISOString(); } export function capitalize(str: string): string { return str.charAt(0).toUpperCase() + str.slice(1); }
Linking and Using:
bash# 1. Build package cd ~/projects/my-utils npm run build npm link # 2. Use in project cd ~/projects/my-app npm link my-utils # 3. Use in code import { formatDate, capitalize } from 'my-utils'; console.log(formatDate(new Date())); console.log(capitalize('hello'));
Performance Considerations
1. Link vs Install
| Feature | npm link | npm install |
|---|---|---|
| Speed | Fast (symbolic link) | Slow (copy files) |
| Disk Space | Low (shared files) | High (independent copies) |
| Real-time Updates | Yes | No |
| Production | Not recommended | Recommended |
2. When to Use npm link
- Development phase: Rapid iteration and testing
- Local debugging: Test without publishing
- Multi-project sharing: Multiple projects using the same local package
3. When to Avoid npm link
- Production environment: Use officially published versions
- CI/CD: Use npm install or npm ci
- Performance sensitive: Links may affect performance
Troubleshooting
1. Check Link Status
bash# View global links npm list -g --depth=0 --link=true # View project links npm list --depth=0 --link=true
2. Clean Up Broken Links
bash# Delete node_modules rm -rf node_modules # Reinstall npm install # Re-link npm link my-package
3. View Link Paths
bash# View actual link path readlink node_modules/my-package # macOS/Linux ls -la node_modules/my-package # Windows dir node_modules\my-package
Alternatives
1. Use npm pack
bash# Pack local package cd ~/projects/my-package npm pack # Install in project cd ~/projects/my-project npm install ../my-package/my-package-1.0.0.tgz
2. Use Private Registry
bash# Publish to private registry cd ~/projects/my-package npm publish --registry=https://registry.yourcompany.com # Install in project cd ~/projects/my-project npm install my-package --registry=https://registry.yourcompany.com
3. Use Workspaces
json{ "workspaces": [ "packages/*" ] }
npm link is a powerful tool for local development and testing of npm packages, which can significantly improve development efficiency. Understanding its working principles and best practices is crucial for efficient package development.