Knip Keeps My JS/TS Dependencies Honest (I Wish Python Had It)
Every long-lived JS/TS project I've worked on accumulates the same three kinds of rot: Dependencies in package.json that nothing imports anymore. You added moment , migrated off it, and the line stayed. Exports nothing consumes. A function was public once, the last caller was deleted, the export is still there advertising an API with no users. Whole files that fell out of the import graph but never got deleted, so every new engineer reads them trying to understand code that runs nowhere. None of this breaks the build. That's exactly why it survives. The compiler is happy, the tests pass, and the dead weight compounds quietly until onboarding takes a week and your bundle ships code no user will ever execute. The tool I've settled on for this is knip (by Lars Kappert). I run it on the enterprise codebase I maintain and on basically every other TS project I touch. One command: $ npx knip Unused files (2) src/legacy/formatValue.ts src/hooks/useLegacyModal.ts Unused dependencies (3) lodash package.json moment package.json @types/uuid package.json Unused exports (5) parseLegacy src/parse.ts:42:14 toLegacyDate src/date.ts:9:14 ... Files, dependencies, and exports in one pass, cross-referenced against the actual import graph. It's the first tool I've used that treats all three as the same problem, which they are: something is declared, nothing uses it, delete it. The honest caveat Knip is not zero-config on a real codebase. Anything resolved dynamically, runtime import() , plugin systems, framework entry points it doesn't recognize (Next.js pages, a CLI bin, config files loaded by string), gets flagged as unused when it isn't. You will get false positives on day one. The fix is a knip.json that names your real entry points, and after that it's accurate. But budget an afternoon to tune it before you trust the output enough to delete on it. Anyone who tells you it's instant hasn't run it on a large app. What I actually want Here's the part that bugs me. This problem is not sp