Skip to content
| Marketplace
Sign in
Visual Studio Code>Linters>DeadweightNew to Visual Studio Code? Get it now.
Deadweight

Deadweight

Kalyan Manna

|
10 installs
| (2) | Free
Find unused packages, dead files and unused exports, then remove them safely: every removal is verified with your own build and tests and undone automatically if anything breaks, and you see the known vulnerabilities you delete.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

💀 Deadweight

Your codebase has deadweight. Deadweight finds it.

Version Installs License: MIT

Deadweight is a VS Code extension that finds unused dependencies, dead files and unused exports in JavaScript and TypeScript projects — tells you how safe each one is to delete — and removes them with a preview and one-click undo.

Deadweight findings with safe-to-delete scores


📑 Contents

  • The problem
  • Quick start (1 minute)
  • The complete workflow
  • Understanding the safe-to-delete score
  • The Connection Graph
  • Commands & settings
  • Troubleshooting & FAQ
  • How it works
  • Safety philosophy
  • Development

🚨 The Problem

Modern projects accumulate technical clutter surprisingly fast.

You install a package for a feature that gets removed. You create a utility file that stops being used. You leave behind dependencies from an old implementation.

Over time, these become deadweight: unnecessary dependencies, unused files, larger projects, harder navigation, more maintenance and more technical debt.

Tools that detect dead code already exist — but they print a list of 40 paths in a terminal and leave you to double-check every one before daring to delete anything. Most people never act on it.

Deadweight closes that loop: detect → understand → remove safely → undo if needed.


⚡ Quick start (1 minute)

  1. Install — in VS Code open Extensions (Ctrl+Shift+X / Cmd+Shift+X), search Deadweight, click Install.
  2. Open your project — File → Open Folder… and pick the folder that contains your package.json.
  3. Click the Deadweight icon (🗑️) in the left activity bar → Scan Workspace.
  4. Read the results — every item has a score like high · 98. Hover it to see why.
  5. Click the trash icon at the top of the panel → check the preview → Remove.
  6. Changed your mind? Click Undo.

That's it. The rest of this page explains each step in detail.


🧭 The complete workflow

 Install ─► Open project ─► Scan ─► Read scores ─► Investigate ─► Review & Remove ─► (Undo) ─► Scan again
                              │                        ▲
                              └──► Connection Graph ───┘   (optional: see how everything connects)

Step 1 — Install

  • VS Code: Extensions view → search Deadweight → Install, or press Ctrl+P and run ext install kalyanmanna.deadweight.
  • From a file: download the .vsix from the GitHub releases, then Extensions view → ⋯ → Install from VSIX…

Installing does nothing on its own — Deadweight never runs in the background or on startup. It only works when you ask.

Step 2 — Open your project

Open the folder that directly contains package.json (File → Open Folder…).

💡 If your project lives in a subfolder — e.g. you opened my-projects/ but the app is in my-projects/my-app/ — open my-app itself. Otherwise Deadweight will tell you it can't find a package.json.

Tip: commit your work to git before cleaning up. Then the cleanup shows up as its own, easy-to-review diff.

Step 3 — Scan

Click the Deadweight icon in the activity bar, then Scan Workspace (or run Deadweight: Scan for unused code from the Command Palette).

  • A progress notification appears; you can keep working, or Cancel at any time.
  • The first scan downloads the analysis engines and can take 30–60 seconds; later scans take a few seconds.
  • When it finishes, the panel fills with three groups:
Group What it lists Can Deadweight remove it?
📦 Unused Packages Dependencies in package.json that nothing imports, runs or configures ✅ Yes (uninstalls with your package manager)
🗂️ Unused Files Files no entry point can reach ✅ Yes (moves them to a trash folder)
🧩 Unused Exports Exported functions, classes, constants and types that no file imports ✋ No — you delete the code yourself

If nothing is found you'll see "No deadweight found" — that's a clean project. 🎉

Step 4 — Read the scores

Every finding shows a band and a safe-to-delete score from 0 to 99:

Score Band Meaning Pre-checked?
80–99 🟢 high Independent checks all agree it's unused ✅ Yes
50–79 🟡 medium Probably unused, but something is worth a look No
< 50 🔴 low Could be used in a way that can't be proven (dynamic imports, config, plugins…) No

Hover any finding to read exactly why it got its score — for example "No import found across 5 scanned files; depcheck agrees. Deadweight's graph agrees: nothing imports it." See Understanding the score for all the rules.

Step 5 — Investigate

  • Click a finding to open it: a file opens directly, a package jumps to its line in package.json, an export jumps to the exact function.
  • In the editor, dead files and unused exports are marked with a ⊘ in the gutter and a note like "Deadweight: unused export · high 98" at the end of the line. Unused files are also dimmed in the Explorer.

Unused exports marked in the editor

  • Right-click a finding → Show in Connection Graph to see what it is (or isn't) connected to.

Step 6 — Review & Remove

  1. Tick or untick the checkboxes. High-score packages and files start ticked; medium and low never do.
  2. Click the trash icon at the top of the Deadweight panel (Review & Remove).
  3. A preview opens — nothing has changed yet. It shows:
    • the exact uninstall command (e.g. npm uninstall chalk left-pad lodash),
    • a View package.json diff button,
    • which files will move to .deadweight-trash/<timestamp>/,
    • the checks that will verify the removal (your type check, build and test scripts),
    • a warning if you have uncommitted changes.
  4. Click Remove & verify to go ahead, or Cancel to leave everything as it is.

Review & Remove preview

What actually happens:

  • Packages are uninstalled in one command with your package manager (npm, yarn, pnpm or bun — detected automatically). package.json and your lockfile are backed up first.
  • Files are moved, never deleted, into .deadweight-trash/<timestamp>/ with their folder structure preserved. The trash folder is added to your .gitignore automatically.
  • Unused exports are never touched — open them and delete the code by hand if you agree.

🛡️ Delete a vulnerability

Every unused package shows what removing it really gains: the space it and the dependencies nothing else needs take up in node_modules, and the known vulnerabilities among them (from the npm advisory database, the one npm audit uses):

lodash     high · 98 · 1.3 MB · ⚠ 5 vulns
minimist   high · 98 · 32 KB  · ⚠ 1 vuln

Hover a package for the list of advisories with links. The scan summary and the Review & Remove panel add it up: "Frees 1.4 MB and removes 6 known vulnerabilities (1 critical, 2 high, 3 moderate)." Unused code you never run can still be installed, audited against and exploited in your supply chain; removing it is the cheapest fix there is.

The lookup sends the names and versions of the unused packages (and their exclusive dependencies) to registry.npmjs.org, like npm audit does. Turn it off with deadweight.checkVulnerabilities; sizes are measured locally either way.

✅ Verified removal

Static analysis can only guess. Deadweight checks its work with your project's own checks:

  1. Before removing, it runs the ticked checks: your type check (typecheck / check-types script, or tsc --noEmit), build and test. Checks that already fail are left out, since they can't prove anything.
  2. After removing, it runs the passing ones again.
  3. If one that passed before now fails, the removal is undone automatically. Deadweight reads the error output, names the likely cause (e.g. "Cannot find module 'lodash'" → lodash) and marks it in use, so it stays at the bottom of the score in future scans.

When everything still passes you get "Verified: type check, build and tests still pass", plus the usual Undo. Untick any check in the panel to skip it (your choice is remembered), or turn verification off with deadweight.verifyRemovals.

Step 7 — Undo (if you need to)

  • Right after removing: click Undo in the notification. Files go back to where they were and packages are reinstalled at their exact previous versions.
  • Any time later: click the clock icon at the top of the panel (Restore from Trash) and pick the removal to restore. Every removal is kept until you delete it.

When you're happy with a cleanup, you can delete the .deadweight-trash folder yourself.

Step 8 — Scan again

Click the refresh icon at the top of the panel. The list should be shorter — or show "No deadweight found".


🎯 Understanding the safe-to-delete score

Deadweight never guesses and never uses AI. Every score comes from evidence it can show you, and your code never leaves your machine.

What raises the score — independent engines agreeing:

  • knip found no import of it,
  • depcheck agrees (packages),
  • Deadweight's own connection graph agrees nothing reachable uses it,
  • for exports: the name appears in no other file at all.

What lowers the score — anything that could mean it's still used:

Situation Effect
Loaded by a computed import like import(`./plugins/${name}.js`) or require(x) → low
Referenced by path or name in a config file (webpack, next.config, …) → low / medium
Run by an npm script or CI → medium
Type definitions (@types/*), a peer dependency of another package → low
Plugins and presets loaded by name (ESLint, Babel, PostCSS, …) → medium
Barrel files (index.ts), packages inside a monorepo workspace → medium
An entry file's exports (may be public API) → medium

Agreement can raise a score only within the band its risks allow — a risky item can never climb to high. The score never reaches 100, because nothing is ever certain.


🕸️ The Connection Graph

An interactive map of how every file and package in your project connects — built in milliseconds, fully offline, no scan needed.

Open it with the graph icon at the top of the Deadweight panel, or Deadweight: Show Connection Graph from the Command Palette.

Connection Graph

Reading it

Shape / line Meaning
🟦 square Entry point — where the app starts (main/bin, framework pages, configs, tests, npm scripts)
🟢 circle Used file — reachable from an entry point
🟡 dashed circle Maybe — only reachable through a computed import, can't be proven
🔴 glowing circle Unused — nothing reachable uses it
◆ diamond Package (purple = used, red = unused)
solid line import · dashed: type-only import · dotted: path in a config · yellow dashed: computed import

Using it

To… Do this
See why a file is used or unused Click it — the details panel shows the reason, Imported by and Imports
Open a file Double-click it, or Open file in the details panel
Find a file Type in the search box (press /), Enter jumps to each match in turn
Show only the problems Click the Entry points and Used chips to hide them (their neighbours stay faintly visible for context)
Hide packages Click the Packages chip
See the flow from the entry points Switch the layout to Tree
Zoom Mouse wheel, the + / − buttons, or F to fit everything
Update after editing code Click Rebuild (⟳)

Graph details panel

Your filters and layout are remembered. Very large projects open on the problems only; click a chip to show everything.


💥 Blast radius: what breaks if I change this?

Right-click any JavaScript/TypeScript file (in the Explorer, its editor tab or the editor) → Show Blast Radius. You get every file that depends on it, directly or through other files, and the entry points it reaches (pages, commands, tests):

Blast radius of format.ts: 14 files (5 direct, 9 indirect) · 3 entry points

Pick a file to open it, or Show in Connection Graph to see the whole chain highlighted in orange. In the graph, every file's details panel shows its blast radius with a Highlight what it can break button.


🤖 AI agents (MCP)

Deadweight ships an MCP server, so coding agents can ask how your project connects instead of opening file after file to find out. That's fewer tokens and fewer wrong guesses.

Tool What the agent gets
project_map The compact project map (every file, its imports, entry points, unused code), optionally for one folder
file_info What a file imports, what imports it, whether it's used, and its blast radius
blast_radius Everything a change to a file or package can break, and the entry points affected
import_path The import chain from one file to another file or package
find_unused Unused and maybe-unused files and packages, with reasons

Connect an agent: run Deadweight: Connect AI Agents (MCP) and pick yours.

  • GitHub Copilot (VS Code 1.101+): nothing to do. Deadweight appears in Copilot Chat's Agent mode tools list.
  • Claude Code: registers it with claude mcp add in a terminal.
  • Cursor: adds it to the project's .cursor/mcp.json.
  • Anything else (Windsurf, Claude Desktop, Cline, Zed…): copies an mcpServers config to paste.

The server runs offline on your machine and only reads source files. Agents other than Copilot need Node.js on your PATH.


🛡️ PR guard (GitHub Action)

Stop dead code at the door. The Deadweight action scans every pull request and its base branch, and comments with only what the PR adds: new unused files, packages and exports, with their safe-to-delete score and any known vulnerabilities. Old dead code on the base branch never makes a PR noisy.

Add .github/workflows/deadweight.yml:

name: Deadweight
on: pull_request

permissions:
  contents: read
  pull-requests: write   # to comment

jobs:
  deadweight:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci                       # optional: enables sizes and vulnerability checks
      - uses: Kalyan-github-4/DeadWeight@v1
        with:
          fail-on: none                   # or "new" / "new-high" to fail the check

What you get on each pull request:

  • One comment, updated on every push (never a new one each time): "This pull request adds 1 unused package and 2 unused files", a table with scores and reasons, a warning when the new unused packages carry vulnerabilities, and a 🎉 when the PR removes dead code.
  • Inline warnings on the changed lines of the diff.
  • A job summary, and outputs added, removed, existing, vulnerabilities for later steps.
Input Default
path . Folder to scan; may hold one project or several
fail-on none new: fail when the PR adds unused code · new-high: only for high-confidence findings
comment true Set false to only write the job summary
check-vulnerabilities true Look up known vulnerabilities (run npm ci first)
exclude .gitignore-style patterns, one per line
entry-points Extra entry-point globs, one per line

Pull requests from forks get a read-only token, so they get the job summary and annotations but no comment.


⚙️ Commands & settings

Commands

Command What it does
Deadweight: Scan for unused code Find unused packages, files and exports
Deadweight: Show Connection Graph Open the interactive file & package graph
Deadweight: Review & Remove Preview and remove the checked findings
Deadweight: Restore from Trash Undo any earlier removal
Deadweight: Show Blast Radius See every file a change to this file can break (also on right-click)
Deadweight: Connect AI Agents (MCP) Give Copilot, Claude Code, Cursor and others Deadweight's graph tools
Deadweight: Export Project Map for AI Agents Save or copy a compact map of the project for any AI chat

Settings

Open Settings (Ctrl+,) and search Deadweight.

Setting Default Use it when
deadweight.exclude [] You want to hide some files or packages from the results, as .gitignore-style patterns: legacy/, **/*.stories.tsx, @types/*
deadweight.entryPoints [] A file is run in a way Deadweight can't see (a cron job, a custom loader). Globs like scripts/*.js — they and everything they import count as used
deadweight.minimumConfidence low You only want to see medium+ or high results
deadweight.packageManager auto You want to force npm, yarn, pnpm or bun
deadweight.verifyRemovals true Turn off if your checks are too slow to run twice per removal
deadweight.verifyTimeoutMinutes 10 A check needs longer than 10 minutes (it counts as failed after this)
deadweight.checkVulnerabilities true Turn off to keep package names from being sent to the npm advisory database

Example .vscode/settings.json:

{
  "deadweight.exclude": ["legacy/", "@types/*"],
  "deadweight.entryPoints": ["scripts/*.js"],
  "deadweight.minimumConfidence": "medium"
}

🩺 Troubleshooting & FAQ

"No package.json found in …" You opened a folder above your project. Open the folder that directly contains package.json (File → Open Folder…).

The scan failed. Click Show Details on the error (or View → Output → Deadweight). The scan needs Node.js and npm on your PATH, and an internet connection the first time, because it runs knip and depcheck through npx. The Connection Graph works without either.

The first scan is slow. The first run downloads the analysis engines. Later scans take a few seconds.

Deadweight flagged something I actually use. It's probably loaded in a way no static analysis can see. Add it to deadweight.entryPoints (for files) or deadweight.exclude, and please open an issue — false positives are the thing we care about most.

Does it upload my code anywhere? No. Everything runs locally. No AI, no API key, no telemetry.

Does it delete my files? No. Files are moved to .deadweight-trash/, and every removal can be undone.

Why can't it remove unused exports for me? Deleting code inside a file is a change a human should make and review. Deadweight shows you exactly where each one is.

Does it work in Cursor / Windsurf / VSCodium? Yes — it needs VS Code 1.90 or newer (or a compatible editor). Install it from the .vsix file if the editor can't reach the VS Code Marketplace.

Which projects are supported? JavaScript and TypeScript projects with a package.json — React, Next.js, Vue/Nuxt, Svelte/SvelteKit, Remix, Astro, Gatsby, Angular, Expo/React Native, Node CLIs and servers. Monorepos work, with findings inside workspace packages capped at medium confidence for now.

Requirements

  • VS Code 1.90 or newer
  • Node.js and npm on your PATH (for the scan)
  • Internet access for the first scan

🧠 How it works

                        ┌─────────────┐
                        │   Project   │
                        └──────┬──────┘
          ┌────────────────────┼────────────────────┐
          ▼                    ▼                    ▼
        knip               depcheck          Deadweight graph
  (files, packages,     (second opinion     (its own import graph:
      exports)            on packages)       entry points → reachability)
          └────────────────────┼────────────────────┘
                               ▼
                 Safe-to-delete score + reasons
                               │
                    ┌──────────┴──────────┐
                    ▼                     ▼
               ✅ Required          💀 Deadweight
                                         │
                            Review → Remove → Undo

Deadweight's own graph finds your entry points (main/bin/exports in package.json, framework conventions for Next.js, Nuxt, SvelteKit, Remix, Astro, Gatsby, Angular and Expo, npm scripts, CI workflows, config files and tests), resolves every import (relative paths, index files, .js→.ts, tsconfig/jsconfig path aliases, monorepo packages, file paths in configs and build scripts) and walks from the entry points to see what's reachable. When independent engines agree, confidence goes up; anything they can't prove lowers it.


🔐 Safety Philosophy

Deadweight should never encourage developers to blindly delete code.

A file or dependency can appear unused while still being required through:

  • Dynamic imports
  • Configuration
  • Build tooling
  • Runtime behavior
  • Framework conventions
  • External consumers

That's why Deadweight is an analysis and decision tool, not an auto-deleter:

  • every finding explains itself,
  • uncertain items are never pre-checked,
  • nothing is removed without a preview,
  • files go to a trash folder instead of being deleted,
  • and every removal can be undone.

🧪 Development

git clone https://github.com/Kalyan-github-4/DeadWeight.git
cd DeadWeight
npm install
npm run compile

Press F5 in VS Code to launch an Extension Development Host with Deadweight loaded.

Script What it does
npm run compile Type-check, lint and build
npm run watch Rebuild on every change
npm run test:unit Unit tests, including the zero-false-positive release gate on the fixture projects
npm run vsix Build deadweight-<version>.vsix

Tech stack: VS Code Extension API · TypeScript · Node.js · knip & depcheck · Cytoscape.js


🗺️ Roadmap

  • [x] Unused dependency detection
  • [x] Dead-file analysis
  • [x] Unused export detection
  • [x] Safe-to-delete score with explanations
  • [x] Connection graph visualization
  • [x] One-click cleanup with undo
  • [x] Configurable safety rules
  • [x] Framework-specific analysis
  • [ ] Automatically find projects in subfolders
  • [ ] Full monorepo support (cross-workspace verification)
  • [ ] Bundled engines for faster, fully offline scans
  • [ ] CI/CD integration

📄 License

MIT © Kalyan Manna

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft