depshred 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,201 +1,238 @@
1
- <p align="center">
2
- <img src="https://raw.githubusercontent.com/gozajpeg/depshred/master/assets/depshred.webp" width="200" alt="depshred logo">
3
- </p>
4
-
5
- <h1 align="center">depshred</h1>
6
-
7
- <p align="center">
8
- <em>Clean up your node_modules. Stop installing stuff Node already has.</em>
9
- </p>
10
-
11
- <p align="center">
12
- <img src="https://img.shields.io/badge/run_with-npx_depshred-111111?style=flat-square" alt="Run with npx">
13
- <img src="https://img.shields.io/badge/node.js-18%2B_%7C_20%2B_%7C_22%2B-111111?style=flat-square" alt="Node Support">
14
- <img src="https://img.shields.io/badge/version-1.0.1-111111?style=flat-square" alt="version 1.0.0">
15
- <img src="https://img.shields.io/badge/license-MIT-111111?style=flat-square" alt="MIT license">
16
- </p>
17
-
18
- ---
19
-
20
- Ever look at your `node_modules` folder and wonder why it takes up half your hard drive?
21
-
22
- When you follow tutorials or ask AI to write code, it is super easy to end up with 30 different packages installed for things modern Node can already do by itself. Stuff like `dotenv`, `uuid`, or `rimraf` do not need to be in your project anymore. Node already knows how to do all of that.
23
-
24
- `depshred` looks through your project, finds packages you do not actually need, and shows you how to swap them for simple code that comes with Node.
25
-
26
- ---
27
-
28
- ## Quick start
29
-
30
- You do not even need to install anything first. Just open your terminal inside your project folder and run:
31
-
32
- ```bash
33
- npx depshred
34
- ```
35
-
36
- If your project lives in another folder, just tell it where:
37
-
38
- ```bash
39
- npx depshred ./path/to/your-project
40
- ```
41
-
42
- Using pnpm or bun instead of npm? That works too:
43
-
44
- ```bash
45
- pnpm dlx depshred
46
- bunx depshred
47
- ```
48
-
49
- ---
50
-
51
- ## What it looks like
52
-
53
- Here is what you see when you run it in your terminal:
54
-
55
- <p align="center">
56
- <img src="https://raw.githubusercontent.com/gozajpeg/depshred/master/assets/view01.webp" width="100%" alt="depshred terminal interface">
57
- </p>
58
-
59
- You get an easy list you can move through with your arrow keys:
60
-
61
- ```text
62
- +--------------------------------------------------------------------------+
63
- | depshred v1.0.1 (Node v20.12.0) |
64
- | Target: ./my-project |
65
- +--------------------------------------------------------------------------+
66
- | Total Scanned: 24 dependencies |
67
- | |
68
- | [CRITICAL] 2 packages have native Node.js replacements (saves ~182 KB) |
69
- | [UNUSED] 1 package has 0 imports (run: npm uninstall rimraf) |
70
- | [WARN] 1 package is dormant >3y (0 sub-deps, self-contained) |
71
- | [OK] 20 packages are lean and actively maintained |
72
- +--------------------------------------------------------------------------+
73
-
74
- Select a dependency to inspect (Use arrow keys, Enter to inspect):
75
- > [CRITICAL] dotenv Native Node.js built-in available (saves ~72 KB)
76
- [CRITICAL] uuid Native Node.js built-in available (saves ~110 KB)
77
- [UNUSED] rimraf 0 imports found in project source code
78
- [WARN] ms Dormant >3 years | 0 sub-dependencies (self-contained)
79
- [OK] fastify Active, schema-compiled and lean
80
- ```
81
-
82
- ---
83
-
84
- ## What it checks for
85
-
86
- When you run `depshred`, it checks three main things:
87
-
88
- 1. **Stuff Node already has built in**
89
- Do you really need `dotenv` when Node can load `.env` files on its own? Do you need `uuid` when Node has `crypto.randomUUID()`? `depshred` finds every file and exact line number where you use these, and shows you the quick built-in way to replace them.
90
-
91
- 2. **Packages you installed but never use**
92
- Ever ran `npm install` for a test or a guide, forgot about it, and left it sitting in your `package.json`? `depshred` scans your whole project. If you never imported it anywhere, it tells you straight up: `npm uninstall <package>`.
93
-
94
- 3. **Old or abandoned packages**
95
- It checks npm to see how big each package is and whether anyone has touched it in the last 3 years. If a package is small, has zero other packages inside it, and just works, `depshred` lets you know so you do not have to worry.
96
-
97
- ```text
98
- Your package.json
99
- |
100
- +------------------+------------------+
101
- | | |
102
- v v v
103
- 1. Already in Node? 2. Used in code? 3. npm check
104
- (dotenv, uuid, etc.) (0 imports found) (file size, age)
105
- | | |
106
- v v v
107
- Use Node built-ins Safe to delete Good to know
108
- (saves disk space) (npm uninstall) (see how big it is)
109
- ```
110
-
111
- ---
112
-
113
- ## Extra options
114
-
115
- Need to run it inside a script or change how it works? Here are the flags you can use:
116
-
117
- | Flag | What it does |
118
- | :--- | :--- |
119
- | `--check` | Checks your project and stops with an error if it finds bad or useless packages. Great for GitHub Actions. |
120
- | `--strict` | Like `--check`, but also stops on small warnings. |
121
- | `--json` | Prints results as JSON so you can read them with code. |
122
- | `--no-interactive` | Skips the arrow-key menu and just prints a plain table. |
123
- | `--path <folder>` | Checks a different folder instead of where you are right now. |
124
- | `--dormant-years <num>` | How many years without updates before calling a package old (defaults to 3). |
125
- | `--ignore <names>` | Comma-separated names of packages you want to skip. |
126
- | `--init-skill [app]` | Adds instructions to your AI editor so it stops installing packages you do not need. |
127
- | `--help`, `-h` | Shows all available flags. |
128
- | `--version`, `-v` | Shows the version number. |
129
-
130
- ---
131
-
132
- ## Teach your AI editor to stop installing junk
133
-
134
- If you use AI coding tools like Cursor, Claude, Windsurf, or GitHub Copilot, you have probably seen them run `npm install` for every single little thing. Most of the time, Node already has what they are trying to download.
135
-
136
- You can teach your AI helper to check first before installing:
137
-
138
- ```bash
139
- # Pick your editor from a menu:
140
- npx depshred --init-skill
141
-
142
- # Or pick your editor directly:
143
- npx depshred --init-skill cursor # For Cursor (.cursor/rules)
144
- npx depshred --init-skill copilot # For GitHub Copilot (.github)
145
- npx depshred --init-skill windsurf # For Windsurf (.windsurf/rules)
146
- npx depshred --init-skill claude # For Claude Code (CLAUDE.md)
147
- npx depshred --init-skill cline # For Cline (.clinerules)
148
- npx depshred --init-skill antigravity # For Antigravity (.agents/skills)
149
- npx depshred --init-skill agents # For general agents (AGENTS.md)
150
- npx depshred --init-skill all # Sets up all of them at once
151
- ```
152
-
153
- Want to see all the skill files and how they work? Check out [SKILLS.md](SKILLS.md).
154
-
155
- ---
156
-
157
- ## Save your settings
158
-
159
- If there is a package you want `depshred` to leave alone, you can save your preferences right inside your `package.json`:
160
-
161
- ```json
162
- {
163
- "depshred": {
164
- "ignore": ["fast-deep-equal"],
165
- "dormantYears": 4
166
- }
167
- }
168
- ```
169
-
170
- ---
171
-
172
- ## What projects work with it?
173
-
174
- Pretty much any modern Node.js project:
175
-
176
- - **Any framework:** Express, Fastify, Next.js, NestJS, Koa, or plain Node scripts.
177
- - **Any module style:** Both `import` (ES Modules) and `require` (CommonJS).
178
- - **JavaScript and TypeScript:** `.js`, `.ts`, `.jsx`, `.tsx`, `.mjs`, `.cjs`.
179
- - **Projects with multiple folders:** Works with monorepos using the `--path` flag.
180
-
181
- ---
182
-
183
- ## Questions you might have
184
-
185
- **Does it change my code automatically?**
186
- No. `depshred` never touches your code behind your back. It shows you the file, the line number, and the built-in Node replacement. You decide what to change and when.
187
-
188
- **Does it need a database or send my code to some server?**
189
- No. Everything runs right on your computer. It only talks to the public npm website to check package sizes and update dates. It saves that info in your computer's temporary folder for a day so it stays fast.
190
-
191
- **What if an old package works fine and does not need updates?**
192
- Not every old package is broken. Some small tools are simply finished and do not need changes. `depshred` checks if the package has zero sub-packages. If it is small and self-contained, it gives you a soft heads-up, not a red error. You can also add it to your ignore list.
193
-
194
- **Does it work with Python or Go?**
195
- No, this is built only for Node.js and npm projects.
196
-
197
- ---
198
-
199
- ## License
200
-
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/gozajpeg/depshred/master/assets/depshred.webp" width="200" alt="depshred logo">
3
+ </p>
4
+
5
+ <h1 align="center">depshred</h1>
6
+
7
+ <p align="center">
8
+ <em>Clean up your node_modules. Stop installing stuff Node already has.</em>
9
+ </p>
10
+
11
+ <p align="center">
12
+ <img src="https://img.shields.io/badge/run_with-npx_depshred-111111?style=flat-square" alt="Run with npx">
13
+ <img src="https://img.shields.io/badge/node.js-18%2B_%7C_20%2B_%7C_22%2B-111111?style=flat-square" alt="Node Support">
14
+ <img src="https://img.shields.io/badge/version-1.0.2-111111?style=flat-square" alt="version 1.0.0">
15
+ <img src="https://img.shields.io/badge/license-MIT-111111?style=flat-square" alt="MIT license">
16
+ </p>
17
+
18
+ ---
19
+
20
+ Ever look at your `node_modules` folder and wonder why it takes up half your hard drive?
21
+
22
+ When you follow tutorials or ask AI to write code, it is super easy to end up with 30 different packages installed for things modern Node can already do by itself. Stuff like `dotenv`, `uuid`, or `rimraf` do not need to be in your project anymore. Node already knows how to do all of that.
23
+
24
+ `depshred` looks through your project, finds packages you do not actually need, and shows you how to swap them for simple code that comes with Node.
25
+
26
+ ---
27
+
28
+ ## Quick start
29
+
30
+ You do not even need to install anything first. Just open your terminal inside your project folder and run:
31
+
32
+ ```bash
33
+ npx depshred
34
+ ```
35
+
36
+ If your project lives in another folder, just tell it where:
37
+
38
+ ```bash
39
+ npx depshred ./path/to/your-project
40
+ ```
41
+
42
+ Using pnpm or bun instead of npm? That works too:
43
+
44
+ ```bash
45
+ pnpm dlx depshred
46
+ bunx depshred
47
+ ```
48
+
49
+ ---
50
+
51
+ ## What it looks like
52
+
53
+ Here is what you see when you run it in your terminal:
54
+
55
+ <p align="center">
56
+ <img src="https://raw.githubusercontent.com/gozajpeg/depshred/master/assets/view01.webp" width="100%" alt="depshred terminal interface">
57
+ </p>
58
+
59
+ You get an easy list you can move through with your arrow keys:
60
+
61
+ ```text
62
+ +--------------------------------------------------------------------------+
63
+ | depshred v1.0.2 (Node v20.12.0) |
64
+ | Target: ./my-project |
65
+ +--------------------------------------------------------------------------+
66
+ | Total Scanned: 24 dependencies |
67
+ | |
68
+ | [CRITICAL] 2 packages have native Node.js replacements (saves ~182 KB) |
69
+ | [UNUSED] 1 package has 0 imports (run: npm uninstall rimraf) |
70
+ | [WARN] 1 package is dormant >3y (0 sub-deps, self-contained) |
71
+ | [OK] 20 packages are lean and actively maintained |
72
+ +--------------------------------------------------------------------------+
73
+
74
+ Select a dependency to inspect (Use arrow keys, Enter to inspect):
75
+ > [CRITICAL] dotenv Native Node.js built-in available (saves ~72 KB)
76
+ [CRITICAL] uuid Native Node.js built-in available (saves ~110 KB)
77
+ [UNUSED] rimraf 0 imports found in project source code
78
+ [WARN] ms Dormant >3 years | 0 sub-dependencies (self-contained)
79
+ [OK] fastify Active, schema-compiled and lean
80
+ ```
81
+
82
+ ---
83
+
84
+ ## What it checks for
85
+
86
+ When you run `depshred`, it checks three main things:
87
+
88
+ 1. **Stuff Node already has built in**
89
+ Do you really need `dotenv` when Node can load `.env` files on its own? Do you need `uuid` when Node has `crypto.randomUUID()`? `depshred` finds every file and exact line number where you use these, and shows you the quick built-in way to replace them.
90
+
91
+ 2. **Packages you installed but never use**
92
+ Ever ran `npm install` for a test or a guide, forgot about it, and left it sitting in your `package.json`? `depshred` scans your whole project. If you never imported it anywhere, it tells you straight up: `npm uninstall <package>`.
93
+
94
+ 3. **Old or abandoned packages**
95
+ It checks npm to see how big each package is and whether anyone has touched it in the last 3 years. If a package is small, has zero other packages inside it, and just works, `depshred` lets you know so you do not have to worry.
96
+
97
+ ```text
98
+ Your package.json
99
+ |
100
+ +------------------+------------------+
101
+ | | |
102
+ v v v
103
+ 1. Already in Node? 2. Used in code? 3. npm check
104
+ (dotenv, uuid, etc.) (0 imports found) (file size, age)
105
+ | | |
106
+ v v v
107
+ Use Node built-ins Safe to delete Good to know
108
+ (saves disk space) (npm uninstall) (see how big it is)
109
+ ```
110
+
111
+
112
+ ---
113
+
114
+ ## What packages can depshred replace?
115
+
116
+ To be completely honest: no tool can replace every single package in the world. Node does not have a built-in 3D engine to replace `three.js` or a built-in database to replace `pg`.
117
+
118
+ Instead, `depshred` targets the **most common sources of accidental bloat**: legacy packages that modern Node already includes for free, and heavy monolithic libraries with modern lightweight replacements.
119
+
120
+ ### 1. Modern Node.js built-ins (Zero packages needed)
121
+
122
+ | Legacy Package | Built-in Node Feature | Supported in | What replaces it |
123
+ | :--- | :--- | :--- | :--- |
124
+ | **`dotenv`** | `--env-file` | Node 20.6+ | `node --env-file=.env app.js` |
125
+ | **`uuid`** | `crypto.randomUUID()` | Node 14.17+ / 16.7+ | `crypto.randomUUID()` |
126
+ | **`rimraf`** | `fs.rmSync()` / `fs.rm()` | Node 14.14+ | `fs.rmSync(path, { recursive: true, force: true })` |
127
+ | **`mkdirp`** | `fs.mkdirSync()` / `fs.mkdir()` | Node 10.12+ | `fs.mkdirSync(path, { recursive: true })` |
128
+ | **`nodemon`** | `node --watch` | Node 18.11+ | `node --watch app.js` |
129
+ | **`axios`** | `fetch()` | Node 18+ | Native `fetch` and `AbortController` |
130
+ | **`node-fetch`** | `fetch()` | Node 18+ | Native `fetch` and `AbortController` |
131
+ | **`glob`** | `fs.glob()` | Node 22+ | Native file matching in `node:fs` |
132
+ | **`querystring`** | `URLSearchParams` | Node 10+ | Built-in `URLSearchParams` |
133
+
134
+ ### 2. Lightweight modern alternatives
135
+
136
+ | Heavy Package | Suggested Alternative | What you save |
137
+ | :--- | :--- | :--- |
138
+ | **`zod`** | `valibot` or `arktype` | Saves ~5.5 MB unpacked (~90% bundle size reduction) |
139
+ | **`moment`** | `dayjs` or native `Intl` | Saves ~4 MB unpacked |
140
+ | **`lodash`** | `es-toolkit` or modern JS | Saves ~1.5 MB unpacked |
141
+ | **`chalk`** | `picocolors` | Saves ~100 KB and drops dependency chain |
142
+ | **`classnames`** | `clsx` | Drop-in API, faster, zero dependencies |
143
+ | **`bcrypt`** | `bcryptjs` or native `crypto` | Removes heavy C++ `node-gyp` build tools |
144
+ | **`deep-equal`** | `fast-deep-equal` | Sub-1KB, faster comparisons |
145
+
146
+ > *Everything else in your project is still scanned for 0-import unused packages, heavy sizes (>5MB), and unmaintained/abandoned code (>3 years old).*
147
+
148
+ ---
149
+
150
+ ## Extra options
151
+
152
+ Need to run it inside a script or change how it works? Here are the flags you can use:
153
+
154
+ | Flag | What it does |
155
+ | :--- | :--- |
156
+ | `--check` | Checks your project and stops with an error if it finds bad or useless packages. Great for GitHub Actions. |
157
+ | `--strict` | Like `--check`, but also stops on small warnings. |
158
+ | `--json` | Prints results as JSON so you can read them with code. |
159
+ | `--no-interactive` | Skips the arrow-key menu and just prints a plain table. |
160
+ | `--path <folder>` | Checks a different folder instead of where you are right now. |
161
+ | `--dormant-years <num>` | How many years without updates before calling a package old (defaults to 3). |
162
+ | `--ignore <names>` | Comma-separated names of packages you want to skip. |
163
+ | `--init-skill [app]` | Adds instructions to your AI editor so it stops installing packages you do not need. |
164
+ | `--help`, `-h` | Shows all available flags. |
165
+ | `--version`, `-v` | Shows the version number. |
166
+
167
+ ---
168
+
169
+ ## Teach your AI editor to stop installing junk
170
+
171
+ If you use AI coding tools like Cursor, Claude, Windsurf, or GitHub Copilot, you have probably seen them run `npm install` for every single little thing. Most of the time, Node already has what they are trying to download.
172
+
173
+ You can teach your AI helper to check first before installing:
174
+
175
+ ```bash
176
+ # Pick your editor from a menu:
177
+ npx depshred --init-skill
178
+
179
+ # Or pick your editor directly:
180
+ npx depshred --init-skill cursor # For Cursor (.cursor/rules)
181
+ npx depshred --init-skill copilot # For GitHub Copilot (.github)
182
+ npx depshred --init-skill windsurf # For Windsurf (.windsurf/rules)
183
+ npx depshred --init-skill claude # For Claude Code (CLAUDE.md)
184
+ npx depshred --init-skill cline # For Cline (.clinerules)
185
+ npx depshred --init-skill antigravity # For Antigravity (.agents/skills)
186
+ npx depshred --init-skill agents # For general agents (AGENTS.md)
187
+ npx depshred --init-skill all # Sets up all of them at once
188
+ ```
189
+
190
+ Want to see all the skill files and how they work? Check out [SKILLS.md](SKILLS.md).
191
+
192
+ ---
193
+
194
+ ## Save your settings
195
+
196
+ If there is a package you want `depshred` to leave alone, you can save your preferences right inside your `package.json`:
197
+
198
+ ```json
199
+ {
200
+ "depshred": {
201
+ "ignore": ["fast-deep-equal"],
202
+ "dormantYears": 4
203
+ }
204
+ }
205
+ ```
206
+
207
+ ---
208
+
209
+ ## What projects work with it?
210
+
211
+ Pretty much any modern Node.js project:
212
+
213
+ - **Any framework:** Express, Fastify, Next.js, NestJS, Koa, or plain Node scripts.
214
+ - **Any module style:** Both `import` (ES Modules) and `require` (CommonJS).
215
+ - **JavaScript and TypeScript:** `.js`, `.ts`, `.jsx`, `.tsx`, `.mjs`, `.cjs`.
216
+ - **Projects with multiple folders:** Works with monorepos using the `--path` flag.
217
+
218
+ ---
219
+
220
+ ## Questions you might have
221
+
222
+ **Does it change my code automatically?**
223
+ No. `depshred` never touches your code behind your back. It shows you the file, the line number, and the built-in Node replacement. You decide what to change and when.
224
+
225
+ **Does it need a database or send my code to some server?**
226
+ No. Everything runs right on your computer. It only talks to the public npm website to check package sizes and update dates. It saves that info in your computer's temporary folder for a day so it stays fast.
227
+
228
+ **What if an old package works fine and does not need updates?**
229
+ Not every old package is broken. Some small tools are simply finished and do not need changes. `depshred` checks if the package has zero sub-packages. If it is small and self-contained, it gives you a soft heads-up, not a red error. You can also add it to your ignore list.
230
+
231
+ **Does it work with Python or Go?**
232
+ No, this is built only for Node.js and npm projects.
233
+
234
+ ---
235
+
236
+ ## License
237
+
201
238
  [MIT](LICENSE).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "depshred",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Shred dependency bloat. Embrace modern Node.",
5
5
  "type": "module",
6
6
  "main": "./src/cli.js",
package/src/cli.js CHANGED
@@ -33,7 +33,7 @@ ${pc.bold('EXAMPLES:')}
33
33
  npx depshred
34
34
  npx depshred --check
35
35
  npx depshred --init-skill cursor
36
- npx depshred ./packages/api --json
36
+ npx depshred ./path/to/your-project --json
37
37
  `;
38
38
 
39
39
  export async function run(rawArgs = []) {
@@ -77,7 +77,7 @@ export async function run(rawArgs = []) {
77
77
  }
78
78
 
79
79
  if (values.version) {
80
- console.log('depshred v1.0.1');
80
+ console.log('depshred v1.0.2');
81
81
  return;
82
82
  }
83
83
 
@@ -29,7 +29,7 @@ export async function runInteractive(auditData) {
29
29
  process.stdout.write('\x1b[2J\x1b[3J\x1b[H');
30
30
 
31
31
  console.log(pc.bold(pc.white('+--------------------------------------------------------------------------+')));
32
- console.log(pc.bold(pc.white(`| depshred v1.0.1 (Target Node: ${targetNode})`)));
32
+ console.log(pc.bold(pc.white(`| depshred v1.0.2 (Target Node: ${targetNode})`)));
33
33
  console.log(pc.bold(pc.white(`| Project: ${projectName} (${totalDependencies} dependencies scanned)`)));
34
34
  console.log(pc.bold(pc.white('+--------------------------------------------------------------------------+')));
35
35
  console.log(pc.red(`| [CRITICAL] ${summary.critical} native replacements (saves ~${formatBytes(totalSaveableBytes)})`));
package/src/locator.js CHANGED
@@ -157,7 +157,76 @@ export async function locateImports(rootDir, declaredDependencies = [], scripts
157
157
  }
158
158
  }
159
159
 
160
- // Rule 3: Scan root configuration files for package names and plugin/preset references
160
+ // Rule 3: Bundler, linter, and build configuration plugins
161
+ for (const pkg of declaredDependencies) {
162
+ if (
163
+ pkg.startsWith('@vitejs/plugin-') ||
164
+ pkg.startsWith('vite-plugin-') ||
165
+ pkg.startsWith('@rollup/plugin-') ||
166
+ pkg.startsWith('rollup-plugin-') ||
167
+ pkg.startsWith('@rolldown/plugin-') ||
168
+ pkg.endsWith('-webpack-plugin') ||
169
+ pkg.startsWith('eslint-config-') ||
170
+ pkg.startsWith('eslint-plugin-') ||
171
+ pkg.startsWith('@eslint/') ||
172
+ pkg.startsWith('prettier-plugin-')
173
+ ) {
174
+ importedSet.add(pkg);
175
+ if (!importsMap.has(pkg)) importsMap.set(pkg, []);
176
+ importsMap.get(pkg).push({
177
+ file: 'package.json',
178
+ line: 1,
179
+ snippet: 'Bundler or linter build plugin'
180
+ });
181
+ }
182
+ }
183
+
184
+ // Rule 4: Compiler engines and toolchain infrastructure
185
+ // Babel toolchain detection: @babel/core, plugins, presets, react-compiler
186
+ const hasBabelTool = declaredDependencies.some((p) =>
187
+ p.includes('babel') || p === '@vitejs/plugin-react' || p.includes('react-compiler')
188
+ );
189
+ if (hasBabelTool) {
190
+ for (const pkg of declaredDependencies) {
191
+ if (
192
+ pkg === '@babel/core' ||
193
+ pkg === '@babel/runtime' ||
194
+ pkg.startsWith('babel-plugin-') ||
195
+ pkg.startsWith('@babel/plugin-') ||
196
+ pkg.startsWith('babel-preset-') ||
197
+ pkg.startsWith('@babel/preset-') ||
198
+ pkg.includes('plugin-babel')
199
+ ) {
200
+ importedSet.add(pkg);
201
+ if (!importsMap.has(pkg)) importsMap.set(pkg, []);
202
+ importsMap.get(pkg).push({
203
+ file: 'package.json',
204
+ line: 1,
205
+ snippet: 'Babel compiler infrastructure / plugin'
206
+ });
207
+ }
208
+ }
209
+ }
210
+
211
+ // PostCSS toolchain detection: postcss, autoprefixer, tailwindcss
212
+ const hasPostcssTool = declaredDependencies.some((p) =>
213
+ p.includes('postcss') || p === 'tailwindcss' || p === 'autoprefixer'
214
+ );
215
+ if (hasPostcssTool) {
216
+ for (const pkg of declaredDependencies) {
217
+ if (pkg === 'postcss' || pkg.startsWith('postcss-')) {
218
+ importedSet.add(pkg);
219
+ if (!importsMap.has(pkg)) importsMap.set(pkg, []);
220
+ importsMap.get(pkg).push({
221
+ file: 'package.json',
222
+ line: 1,
223
+ snippet: 'PostCSS compiler infrastructure / plugin'
224
+ });
225
+ }
226
+ }
227
+ }
228
+
229
+ // Rule 5: Scan root configuration files for package names and plugin/preset references
161
230
  const rootConfigFiles = await getRootConfigFiles(rootDir);
162
231
  for (const configName of rootConfigFiles) {
163
232
  let content;
@@ -174,7 +243,7 @@ export async function locateImports(rootDir, declaredDependencies = [], scripts
174
243
  const escaped = pkg.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
175
244
  const directRegex = new RegExp(`['"]${escaped}['"]|\\b${escaped}\\b`);
176
245
 
177
- // Shorthand matches for common config tools (e.g. "react" for "eslint-plugin-react" or "react-app" for "eslint-config-react-app")
246
+ // Shorthand matches for common config tools
178
247
  let shorthandMatch = false;
179
248
  if (configName.includes('eslint')) {
180
249
  const eslintPlugin = pkg.replace(/^eslint-plugin-/, '');
@@ -200,7 +269,7 @@ export async function locateImports(rootDir, declaredDependencies = [], scripts
200
269
  }
201
270
  }
202
271
 
203
- // Rule 4: Scan package.json scripts for CLI tool references (e.g. nodemon, rimraf, tsc, prettier)
272
+ // Rule 6: Scan package.json scripts for CLI tool references (e.g. nodemon, rimraf, tsc, prettier)
204
273
  for (const [scriptName, scriptCmd] of Object.entries(scripts)) {
205
274
  if (typeof scriptCmd !== 'string') continue;
206
275
  for (const pkg of declaredDependencies) {
@@ -220,7 +289,7 @@ export async function locateImports(rootDir, declaredDependencies = [], scripts
220
289
  }
221
290
  }
222
291
 
223
- // Rule 5: Scan project source files for import / require / export from
292
+ // Rule 7: Scan project source files for import / require / export from
224
293
  for (const filePath of sourceFiles) {
225
294
  let content;
226
295
  try {
package/src/registry.js CHANGED
@@ -1,4 +1,4 @@
1
- import { readFile, writeFile } from 'node:fs/promises';
1
+ import { readFile, writeFile } from 'node:fs/promises';
2
2
  import { tmpdir } from 'node:os';
3
3
  import { join } from 'node:path';
4
4
 
@@ -66,7 +66,7 @@ export async function fetchPackageMetadata(packageName, timeoutMs = 4000) {
66
66
  signal: controller.signal,
67
67
  headers: {
68
68
  Accept: 'application/json',
69
- 'User-Agent': 'depshred-audit/1.0.0'
69
+ 'User-Agent': 'depshred-audit/1.0.2'
70
70
  }
71
71
  });
72
72
 
package/src/reporter.js CHANGED
@@ -9,7 +9,7 @@ export function printScorecard(auditData, options = {}) {
9
9
 
10
10
  console.log('');
11
11
  console.log(pc.bold(pc.white('+--------------------------------------------------------------------------+')));
12
- console.log(pc.bold(pc.white(`| depshred v1.0.1 (Target Node: ${targetNode})`)));
12
+ console.log(pc.bold(pc.white(`| depshred v1.0.2 (Target Node: ${targetNode})`)));
13
13
  console.log(pc.bold(pc.white(`| Project: ${projectName} (${totalDependencies} dependencies scanned)`)));
14
14
  console.log(pc.bold(pc.white('+--------------------------------------------------------------------------+')));
15
15
 
@@ -1,8 +1,14 @@
1
- /**
1
+ /**
2
2
  * Modern Lightweight Package Alternatives Catalog.
3
3
  * Objective replacements for heavy or legacy packages.
4
4
  */
5
5
  export const ALT_RULES = [
6
+ {
7
+ name: 'zod',
8
+ lighter: 'valibot',
9
+ description: 'Zod is ~5.9MB unpacked (~14KB gzipped). Replace with valibot (modular, sub-1KB per schema) or arktype for 10x smaller bundles.',
10
+ savings: '~5.5MB unpacked (~90% bundle reduction)'
11
+ },
6
12
  {
7
13
  name: 'moment',
8
14
  lighter: 'dayjs',
@@ -21,10 +27,22 @@ export const ALT_RULES = [
21
27
  description: 'Large dependency chain in v4/v5. Replace with picocolors (sub-7KB, 0 sub-dependencies).',
22
28
  savings: '~100KB'
23
29
  },
30
+ {
31
+ name: 'classnames',
32
+ lighter: 'clsx',
33
+ description: 'Legacy classnames utility. Replace with clsx (drop-in API, faster, zero dependencies).',
34
+ savings: '~50KB'
35
+ },
24
36
  {
25
37
  name: 'bcrypt',
26
38
  lighter: 'bcryptjs',
27
39
  description: 'Requires node-gyp C++ compilation toolchain. Replace with pure JS bcryptjs or native crypto.scrypt.',
28
40
  savings: 'Eliminates native build toolchain dependency'
41
+ },
42
+ {
43
+ name: 'deep-equal',
44
+ lighter: 'fast-deep-equal',
45
+ description: 'Legacy recursive comparison. Replace with fast-deep-equal (sub-1KB, faster) or native assert.deepStrictEqual.',
46
+ savings: '~80% faster and 0 sub-dependencies'
29
47
  }
30
- ];
48
+ ];