# Find and remove unused code with Knip

Used: knip@4.3.0

[Knip](https://knip.dev) is a great tool that lets you find any piece of code you're not using anymore in your app, this includes files that are not imported, exports that are not used, old dependencies you never uninstalled, transient dependencies that you use through another one, and more things.

This is really useful to keep your codebase clean and help reduce the build time of your app (since the build becomes larger as the app grows).

First install with from npm

```sh
npm add -D knip
```

Then we can create a `knip.config.ts` file in our repository:

```ts {% path="knip.config.ts" %}
import type { KnipConfig } from "knip";

export default {
  entry: [
    "server/index.js",
    "app/**/*.test.ts",
    "app/**/*.test.tsx",
  ],
  ignore: ["types/**/*.d.ts"],
  remix: { config: "remix.config.mjs" },
  rules: {
    binaries: "error",
    classMembers: "error",
    dependencies: "error",
    devDependencies: "error",
    duplicates: "error",
    enumMembers: "error",
    exports: "error",
    files: "error",
    nsExports: "error",
    nsTypes: "error",
    types: "error",
    unlisted: "error",
    unresolved: "error",
  },
} satisfies KnipConfig;
```

This is the configuration I use, mark everything as errors (no warnings), define the entry files of the app like test files or the HTTP server, ignore any `d.ts` files since those can define globals and finally tell it where to find my `remix.config.mjs` file, this is only if you're also using Remix.

Now I like to add an `unused` script to my `package.json` that just does `knip`, and you can run it like this:

```sh
npm run unused
# or npx knip
```

Then it will run and list you every file you're not using, export not being imported, etc. You can clear them and run it again and it will show you this message:

```sh
$ knip
✂️  Excellent, Knip found no issues.
```

Finally, you can add it to your CI to ensure you don't leave unused code on a PR. With GitHub Actions it could look like this:

```yml {% path=".github/workflows/ci.yml" %}
jobs:
  ci:
    name: CI
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Use Node LTS
        uses: actions/setup-node@v4

      - name: Install dependencies
        uses: bahmutov/npm-install@v1

      - name: Unused Code
        run: yarn unused
```

And now if your PR leaves or adds unused code, it will fails on CI until you remove that code, helping you stay neat and tidy.
