# bun/prefer-local-module

> Require importing a package through the module in your project that wraps it

A project often wraps a package in its own module, for example to give an HTTP client a base URL, a timeout and logging. A file that imports the package directly skips all of that, and nothing tells you.

The rule does nothing until you list the packages in `modules`. It then checks `import`, `export .. from`, `import()` and `require()`. The name must match exactly, so with `axios` listed, `axios/lib` isn't reported.

`--fix` changes the import to your module.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

```toml bunfig.toml
[lint.rules]
"bun/prefer-local-module" = "error" # or "warn"
```

Every option, set to its default:

```toml bunfig.toml
[lint.rules]
"bun/prefer-local-module" = ["error", {
  modules = [], # list of objects
  exemptFiles = [], # list of strings
}]
```

{/* End of the generated section. */}

## Examples

These examples use this configuration:

```toml bunfig.toml
[lint.rules]
"bun/prefer-local-module" = ["error", {
  modules = [{ package = "axios", use = "@/http" }],
}]
```

Reported:

{/* bad {"options": [{"modules": [{"package": "axios", "use": "@/http"}]}]} */}
```ts
import axios from "axios";

const users = await axios.get("/users");
```

Not reported:

{/* good {"options": [{"modules": [{"package": "axios", "use": "@/http"}]}]} */}
```ts
import axios from "@/http";

const users = await axios.get("/users");
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `modules` | `[]` | The wrapped packages. See below. |
| `exemptFiles` | `[]` | Files that can import the packages directly. List the wrapper itself here. |

Each entry in `modules` has:

| Key | What it is |
| --- | --- |
| `package` | The package that must not be imported directly. Required. |
| `use` | The specifier to import instead. Required. |
| `default` | The name your module uses to export the package's default export. |
| `names` | Exports that have a different name in your module, like `{ "isCancel": "wasCancelled" }`. |

`default` and `names` only matter for `--fix`. With `default` set to `"http"`, `import axios from "axios"` becomes `import { http as axios } from "@/http"`. If either is set, only `import` statements are fixed, and not `import * as` or `import type`.

An entry in `exemptFiles` is the end of a path, in whole names. `http.ts` matches `src/http.ts` but not `src/other-http.ts`.

{/* good {"filename": "src/http.ts", "options": [{"modules": [{"package": "axios", "use": "@/http"}], "exemptFiles": ["src/http.ts"]}]} */}
```ts
import axios from "axios";

export default axios.create({ baseURL: "https://api.example.com", timeout: 5000 });
```
