Auto-fix
Run Knip as you normally would, and if the report looks good then run it again
with the --fix
flag to let Knip automatically apply fixes. It fixes the
following issue types:
- Remove
export
keyword for unused exports and exported types - Remove
export default
keywords for unused default exports - Remove exports, re-exports and exported types
- Remove unused enum members
- Remove unused class members (disabled by default)
- Remove unused
dependencies
anddevDependencies
frompackage.json
- Remove unused files
Flags
Add the --fix
flag to remove unused exports and dependencies:
knip --fix
Add --allow-remove-files
to allow Knip to remove unused files:
knip --fix --allow-remove-files
Use --fix-type
to fix only specific issue types:
files
exports
types
dependencies
Example:
knip --fix-type exports,typesknip --fix-type exports --fix-type types # same as above
Demo
Post-fix
After Knip has fixed issues, there are four things to consider:
1. Use a formatter
Use a tool like Prettier or Biome if the code needs formatting. Knip removes the minimum amount of code while leaving it in a working state.
2. Unused variables
Use a tool like ESLint or Biome to find and remove unused variables inside files. Even better, try remove-unused-vars to remove unused variables within files.
This may result in more deleted code, and Knip may then find more unused code. Rinse and repeat!
3. Unused dependencies
Verify changes in package.json
and update dependencies using your package
manager.
npm install
pnpm install
bun install
yarn
4. Install unlisted dependencies
If Knip reports unlisted dependencies or binaries, they should be installed.
npm install unlisted-package
pnpm add unlisted-package
bun add unlisted-package
yarn add unlisted-package
Example results
Exports
The export
keyword for unused exports is removed:
export const unused = 1;export default class MyClass {}const unused = 1;class MyClass {}
The default
keyword was also removed here.
Knip removes the whole or part of export declarations:
type Snake = 'python' | 'anaconda';const Owl = 'Hedwig';const Hawk = 'Tony';export type { Snake };export { Owl, Hawk };;;
Re-exports
Knip removes the whole or part of re-exports:
export { Cat, Dog } from './pets';export { Lion, Elephant } from './jungle';export { Elephant } from './jungle'
Also across any chain of re-exports:
export const Hawk = 'Tony';export const Owl = 'Hedwig';const Owl = 'Hedwig';
export * from './module.js';
export { Hawk, Owl } from './barrel.js';export { Hawk } from './barrel.js'
Export assignments
Knip removes individual exported items in “export assignments”, but does not remove the entire export declaration if it’s empty:
export const { a, b } = fn();export const { } = fn();
export const [c, d] = [c, d];export const [, ] = [c, d];
Reason: the right-hand side of the assignment might have side-effects. It’s not safe to always remove the whole declaration. This could be improved in the future (feel free to open an issue/RFC).
Enum members
Unused members of enums are removed:
export enum Directions { North = 1, East = 2, South = 3, West = 4,}
CommonJS
Knip supports CommonJS and removes unused exports:
module.exports = { identifier, unused };module.exports = { identifier, };
module.exports.UNUSED = 1;module.exports['ACCESS'] = 1;
Warning: the right-hand side of such an assignment might have side-effects. Knip currently removes the whole declaration (feel free to open an issue/RFC).
Dependencies
Unused dependencies are removed from package.json
:
{ "name": "my-package", "dependencies": { "rimraf": "*", "unused-dependency": "*" "rimraf": "*" }, "devDependencies": { "unreferenced-package": "5.3.3" } "devDependencies": {}}
experimental
Class membersUnused members of classes can be removed:
export class Rectangle { constructor(public width: number, public height: number) {}
static Key = 1;
area() { return this.width * this.height; }
public get unusedGetter(): string { return 'unusedGetter'; }}
Currently Knip might be too eager removing class members when they’re not
referenced internally but meant to be called by an external library. For
instance, Knip might think componentDidMount
and render
in React class
component are unused and will remove those.
Note that classMembers
aren’t included by default.
What’s not included
Operations that auto-fix does not (yet) perform and why:
- Add unlisted (dev) dependencies to
package.json
(should it go intodependencies
ordevDependencies
? For monorepos in current workspace or root?) - Add unlisted binaries (which package and package version contains the used binary?)
- Fix duplicate exports (which one should removed?)
ISC License © 2024 Lars Kappert