Node.jsPerformanceDependenciesNative FeaturesZero Dep

The Shrinking node_modules: Why You Need Fewer Packages in 2026

B
Backend Lead
Featured Guide 18 min read

Uninstalling is the new Installing.

We used to joke that node_modules was the heaviest object in the universe.

In 2026, Node.js has absorbed the most popular userland libraries into the core runtime. You no longer need Jest, Mocha, Dotenv, Notebooks, or Nodemon.

Deep Dive: Single Executable Applications (SEA)

Node.js now allows you to bundle your script and the runtime into a single binary file.
Combined with zero dependencies, you can distribute a 50MB my-api.exe that runs anywhere without npm install.

02. Goodbye Jest. Hello node:test.

import { test, describe, it } from 'node:test';
import assert from 'node:assert/strict';

describe('My API', () => {
  it('should return 200 OK', () => {
     const val = 1;
     assert.strictEqual(val, 1);
  });
});
                

Running tests is now as simple as node --test. No config files. No transpilers (if using native ESM). Instant startup.

03. Database in the Core

Old Way (External)

npm install sqlite3 (C++ bindings...)

npm install knex

Error: node-gyp rebuild failed...

New Way (Native)

import { DatabaseSync } from 'node:sqlite';
const db = new DatabaseSync(':memory:');
db.exec('CREATE TABLE users...');
                    

05. The Senior Engineer's View

Supply Chain Security

The biggest advantage of removing dependencies isn't just disk space—it's Security.

Every package you add is a potential vector for a supply chain attack. Using native node: modules means you trust the Node.js signing key, not random maintainers on npm.

Interactive Playground

import React, { useState } from 'react';

// 📦 Node.js Core Visualizer

export default function NodeModulesDemo() {
    const [installed, setInstalled] = useState([
        { id: 'jest', name: 'jest', size: '25 MB', native: 'node:test', type: 'removed' },
        { id: 'dotenv', name: 'dotenv', size: '0.5 MB', native: 'node:env', type: 'removed' },
        { id: 'nodemon', name: 'nodemon', size: '3 MB', native: 'node --watch', type: 'removed' },
        { id: 'sqlite3', name: 'sqlite3', size: '12 MB', native: 'node:sqlite', type: 'removed' },
        { id: 'minimist', name: 'minimist', size: '0.2 MB', native: 'node:util', type: 'removed' },
        { id: 'axios', name: 'axios', size: '1.2 MB', native: 'fetch', type: 'removed' }
    ]);
    
    // Initial state: all present.
    // We want to animate their removal.
    
    const [projectSize, setProjectSize] = useState(42); // MB
    const [securityScore, setSecurityScore] = useState(60); // %

    const handleMigrate = (id) => {
        setInstalled(prev => prev.map(pkg => 
            pkg.id === id ? { ...pkg, type: 'migrated' } : pkg
        ));
        
        // Update stats
        const pkg = installed.find(p => p.id === id);
        const sizeVal = parseFloat(pkg.size);
        setProjectSize(s => Math.max(0, s - sizeVal));
        setSecurityScore(s => Math.min(100, s + 5));
    };

    return (
        <div className="bg-slate-50 dark:bg-slate-950 p-8 rounded-3xl border border-slate-200 dark:border-slate-800 shadow-xl">
             <div className="flex flex-col md:flex-row justify-between items-start md:items-end mb-10 gap-6">
                <div>
                     <h3 className="text-3xl font-black text-gray-900 dark:text-white flex items-center gap-3">
                        <span className="text-green-600">🟢</span> Node.js Diet
                    </h3>
                    <p className="text-gray-500 mt-2">Replace userland bloat with Native Core modules.</p>
                </div>
                
                 <div className="flex gap-6">
                    <div className="text-right">
                         <div className="text-xs font-bold text-gray-400 uppercase">Disk Usage</div>
                         <div className="text-3xl font-black text-gray-900 dark:text-white transition-all duration-500">
                             {projectSize.toFixed(1)} <span className="text-sm font-normal text-gray-500">MB</span>
                         </div>
                    </div>
                     <div className="text-right">
                         <div className="text-xs font-bold text-gray-400 uppercase">Trust Score</div>
                         <div className={`text-3xl font-black transition-all duration-500 ${securityScore > 80 ? 'text-green-500' : 'text-orange-500'}`}>
                             {securityScore}<span className="text-sm font-normal text-gray-500">%</span>
                         </div>
                    </div>
                </div>
            </div>

            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                {installed.map((pkg) => {
                    const isMigrated = pkg.type === 'migrated';
                    return (
                        <div 
                            key={pkg.id} 
                            className={`relative p-6 rounded-2xl border transition-all duration-500 overflow-hidden ${
                                isMigrated 
                                ? 'bg-green-50 dark:bg-green-900/10 border-green-200 dark:border-green-900/30 opacity-80' 
                                : 'bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-800 shadow-sm hover:shadow-md'
                            }`}
                        >
                            <div className="flex justify-between items-start mb-4">
                                <div className="p-3 bg-gray-100 dark:bg-black rounded-lg">
                                    <span className={isMigrated ? 'text-green-500' : 'text-gray-500'}>📦</span>
                                </div>
                                {!isMigrated && (
                                    <span className="text-xs font-bold bg-red-100 text-red-600 px-2 py-1 rounded-full border border-red-200">
                                        Deprecated
                                    </span>
                                )}
                                {isMigrated && (
                                     <span className="text-xs font-bold bg-green-100 text-green-600 px-2 py-1 rounded-full border border-green-200 flex items-center gap-1">
                                        <span>🛡️</span> Native
                                    </span>
                                )}
                            </div>
                            
                            <h4 className="font-bold text-lg mb-1">{pkg.name}</h4>
                            <p className="text-xs text-gray-400 mb-6">{pkg.size}</p>
                            
                            {isMigrated ? (
                                <div className="text-sm text-green-700 dark:text-green-400 font-mono flex items-center gap-2">
                                    <span>📟</span> {pkg.native}
                                </div>
                            ) : (
                                <button 
                                    onClick={() => handleMigrate(pkg.id)}
                                    className="w-full py-2 bg-slate-900 dark:bg-white text-white dark:text-black rounded-lg text-sm font-bold flex items-center justify-center gap-2 hover:opacity-90 transition-opacity"
                                >
                                    <span>🗑️</span> Migrate to Native
                                </button>
                            )}
                        </div>
                    );
                })}
            </div>
            
            <div className="mt-8 p-6 bg-blue-50 dark:bg-blue-900/10 rounded-xl border border-blue-200 dark:border-blue-900/30 text-center text-sm text-blue-800 dark:text-blue-300">
                💡 <strong className="font-bold">Did you know?</strong> Starting a Node.js process with zero external CJS dependencies can be up to 4x faster in cold start time.
            </div>
        </div>
    );
}