Skip to content

Resolving Node.js punycode Deprecation Warning in Mongoose

Problem Statement

When using Mongoose with recent Node.js versions (v21+), you may encounter a deprecation warning:

bash
(node:22063) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. 
Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)

This warning occurs because:

  1. Older versions of dependencies use Node.js's built-in punycode module
  2. Node.js deprecated punycode starting in version 21
  3. MongoDB connection URLs (especially those containing international characters) may trigger punycode usage
  4. The issue appears when using Mongoose, but originates from the dependency chain

Commonly affected environments:

  • Node.js v21 or higher
  • Mongoose versions relying on outdated dependencies like uri-js
  • Local development databases or any MongoDB instances using non-ASCII characters in connection strings

1. Update URI-JS Dependency (Best Practice)

Update the uri-js package since it’s the most common source of punycode usage:

bash
npm install uri-js@4.2.2
# or use latest version if available
npm install uri-js@latest

Why this works:

  • Versions before 4.2.0 used Node's built-in punycode
  • 4.2.0+ switched to userland punycode implementation
  • This fixes the warning while maintaining URI parsing functionality

2. Reinstall and Clean Dependencies

Refresh your dependency tree to ensure updated modules:

bash
rm -rf node_modules package-lock.json
npm install

After reinstalling, reconnect to MongoDB using promises:

js
import mongoose from 'mongoose';

const DB_URL = 'mongodb://localhost:27017/your-db';

mongoose.connect(DB_URL)
  .then(() => console.log('Database connected'))
  .catch(err => console.error('Connection error:', err));

3. Upgrade Node.js to 22.14.0+

If possible, upgrade to Node 22.14.0 or later:

bash
nvm install 22.14.0
nvm use 22.14.0

Key benefits:

  • Node.js 22+ includes backported fixes for core modules
  • Many deprecation warnings are resolved in LTS versions
  • Better long-term compatibility with MongoDB ecosystems

4. Use Node 20 LTS (Alternative if Updates Break)

For critical projects where upgrades are problematic, switch to Node 20 LTS:

bash
nvm install 20.5.1
nvm use 20.5.1

WARNING

Avoid this on new projects - Node 20 will reach end-of-life in 2026

Discouraged Approaches

⚠️ Modifying node_modules Directly

Some answers suggest editing files in tr46 module:

js
// In node_modules/tr46/index.js:
const punycode = require('punycode/');  // Instead of 'punycode'

Why not to do this:

  • Changes are lost on reinstalls or updates
  • Breaks package integrity checks
  • Potential security risks from modifications

❌ Uninstalling punycode

Running npm uninstall punycode appears to work but:

  • May break dependencies relying on it
  • The core issue remains in modules that try to use built-in punycode
  • Doesn't address the actual deprecation

⚠️ Suppressing Warnings Globally

Avoid hiding the root problem with:

bash
export NODE_OPTIONS="--no-deprecation"

While useful temporarily, this masks important warnings and should never be used in production.

Verifying Your Fix

Confirm solution effectiveness by:

  1. Adding a postinstall script in package.json:
json
"scripts": {
  "postinstall": "npm list uri-js"
}
  1. Checking installed versions:
bash
npm list uri-js
# Should show 4.2.2+ in output
  1. Testing MongoDB connection while monitoring for warnings:
bash
node --no-deprecation your-app.js 2>&1 | grep -v DeprecationWarning

Additional Context

The punycode warning surfaces in Mongoose connections because:

  1. MongoDB connection strings might contain special characters
  2. Older URI parsers used Node's punycode for URL normalization
  3. The dependency chain typically involves:

Recent versions of these packages have removed punycode dependencies. For most users, upgrading uri-js and reinstalling dependencies resolves the warning permanently while maintaining compatibility with latest Node.js versions.