Why I'm Moving from npm to pnpm
Have you seen the news lately? The JavaScript ecosystem was just hit by a massive supply chain attack. Dozens of packages were compromised, including the very popular TanStack router. As my friend midudev pointed out in his recent video, this wasn't just a glitch—malware was actively stealing developer tokens and wiping disks.
This brings up an uncomfortable question: Is npm secure by default?
As we learned from the incident, the default npm configuration leaves us vulnerable to these kinds of supply chain attacks. But there is a better way. Today, we are going to talk about why migrating to PNPM 11 is not just a performance upgrade, but a critical security move.
And the best part? I'll show you how to migrate your entire team without breaking a sweat.
I personally implemented this process to secure my own workflow and prevent these kinds of attacks from affecting my projects. Since I work on both Mac and Windows machines, I needed a solution that worked seamlessly across both environments, ensuring that my tools were always updated and secure regardless of the OS.
Let's get started!
Why PNPM? The Security and Performance Win
If you watch midudev's breakdown, you'll see why PNPM 11 is highly recommended right now:
- Automatic Attack Blocking: PNPM 11 offers improved security features that block many common supply chain attacks automatically.
- No Phantom Dependencies: Unlike npm, PNPM uses a strict
node_modulesstructure. Your code only has access to what you explicitly declare in yourpackage.json. No more hidden vulnerabilities sneaking in through nested folders. - Content-Addressable Storage: PNPM saves packages in a single global store on your machine. If you have 10 Angular projects, you only store the binaries once. This saves massive amounts of disk space and makes installations lightning-fast.
Think of PNPM as a smart vault for your dependencies, rather than npm's messy filing cabinet.
The Strategy: Muscle Memory with Aliases
The hardest part of changing a tool is muscle memory. We type npm install and npm start hundreds of times a day.
To solve this, our migration strategy uses aliases. We will map npm to pnpm. Your brain keeps typing npm, but your terminal executes the secure, lightning-fast pnpm under the hood.
Here are the scripts to automate this migration for your team. They are safe to run multiple times (idempotent) and will even offer to clean up your old npm cache to save disk space!
For macOS and Linux (Bash / Zsh)
Create a file named migrate-to-pnpm.sh, paste this code, and run it:
#!/bin/bash
# 1. Check if pnpm is already installed
if command -v pnpm &> /dev/null; then
echo "✔ pnpm is already installed ($(pnpm -v))."
else
echo "📦 Installing pnpm..."
curl -fsSL https://get.pnpm.io/install.sh | sh -
fi
# 2. Determine the shell config file
SHELL_NAME=$(basename "$SHELL")
CONF_FILE="$HOME/.${SHELL_NAME}rc"
[ ! -f "$CONF_FILE" ] && CONF_FILE="$HOME/.zshrc"
# 3. Add aliases safely
if ! grep -q "alias npm='pnpm'" "$CONF_FILE"; then
echo -e "\n# pnpm Aliases\nalias npm='pnpm'\nalias npx='pnpm dlx'" >> "$CONF_FILE"
echo "✅ Aliases added to $CONF_FILE"
else
echo "ℹ️ Aliases already exist in $CONF_FILE."
fi
# 4. Ask to clear npm cache
echo ""
read -p "Do you want to clear the old npm cache to save disk space? (y/n): " confirm
if [[ "$confirm" == [yY] || "$confirm" == [yY][eE][sS] ]]; then
echo "🧹 Cleaning npm cache..."
command npm cache clean --force &> /dev/null
echo "✨ Cache cleared."
else
echo "⏭️ Skipping cache clean."
fi
echo "--------------------------------------------------"
echo "🎉 Setup complete! Run: source $CONF_FILE"
echo "--------------------------------------------------"For Windows (PowerShell)
Create a file named migrate-to-pnpm.ps1 and execute it:
# 1. Check if pnpm is already installed
if (Get-Command pnpm -ErrorAction SilentlyContinue) {
Write-Host "✔ pnpm is already installed (version: $(pnpm -v))." -ForegroundColor Cyan
} else {
Write-Host "📦 Installing pnpm..." -ForegroundColor Yellow
iwr https://get.pnpm.io/install.ps1 -useb | iex
}
# 2. Configure PowerShell Profile (Aliases)
$PROFILE_PATH = $PROFILE
if (!(Test-Path $PROFILE_PATH)) {
$dir = Split-Path $PROFILE_PATH
if (!(Test-Path $dir)) { New-Item -Path $dir -ItemType Directory -Force }
New-Item -Path $PROFILE_PATH -ItemType File -Force
}
$ALIAS_CONTENT = @"
# pnpm Aliases
function npm-alias { pnpm `$args }
Set-Alias -Name npm -Value npm-alias -Option ReadOnly, AllScope -Force
function npx-alias { pnpm dlx `$args }
Set-Alias -Name npx -Value npx-alias -Option ReadOnly, AllScope -Force
"@
if (!(Select-String -Path $PROFILE_PATH -Pattern "function npm-alias" -Quiet)) {
Add-Content -Path $PROFILE_PATH -Value $ALIAS_CONTENT
Write-Host "✅ Aliases added to your profile." -ForegroundColor Green
}
# 3. Ask to clear npm cache
Write-Host ""
$confirm = Read-Host "Do you want to clear the old npm cache? (y/n)"
if ($confirm -eq 'y') {
& "npm" cache clean --force
Write-Host "✨ Cache cleared." -ForegroundColor Green
}
Write-Host "--------------------------------------------------"
Write-Host "🎉 Setup complete! Restart your terminal or run: . `$PROFILE"
Write-Host "--------------------------------------------------"Listen, the recent security attacks are a big warning for all of us. Taking just one minute to run these scripts and switch to PNPM 11 is not only about saving disk space. It is about making your coding environment safe. I use both Mac and Windows, and I want my tools to be secure on both. It is the best thing you can do for your daily work.
I really want you to try this today. Set up the aliases, run npm install in your favorite Angular project, and see the results. It is faster, it is safer, and once you try it, you will never want to go back.
See you in the next post, and as always—stay safe and keep coding!
Photo by Brad Starkey on Unsplash
Real Software. Real Lessons.
I share the lessons I learned the hard way, so you can either avoid them or be ready when they happen.
Join 13,800+ developers and readers.
No spam ever. Unsubscribe at any time.