# bun/no-cwd-dependent-path

> Disallow relative paths that depend on the directory the process was started in

`readFileSync("config.json")` doesn't look next to the file that calls it. It looks in the directory the process was started in. The code works when you run it from the project root and fails with `ENOENT` when it runs from anywhere else. Start from `import.meta.dirname` to name a file next to your source.

The rule checks a string or a template literal that starts with a relative path, in these places:

- The `node:fs` and `node:fs/promises` functions, except `glob` and `globSync`. For `copyFile`, `cp`, `link`, and `rename`, both paths are checked. For `symlink`, only the second one is, because the target is relative to the link.
- `path.resolve()`, if every argument is a literal like that.
- `Bun.file()` and `Bun.write()`.

{/* 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/no-cwd-dependent-path" = "error" # or "warn"
```

Every option, set to its default:

```toml bunfig.toml
[lint.rules]
"bun/no-cwd-dependent-path" = ["error", {
  functions = [], # list of strings
}]
```

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

## Examples

Reported:

{/* bad */}
```js
import { readFileSync } from "node:fs";

const config = JSON.parse(readFileSync("config.json", "utf8"));
```

{/* bad {"count": 2} */}
```js
import path from "node:path";

const schema = Bun.file(`schemas/${name}.json`);
const output = path.resolve("dist", "index.js");
```

Not reported:

{/* good */}
```js
import { readFileSync } from "node:fs";
import path from "node:path";

const config = JSON.parse(readFileSync(path.join(import.meta.dirname, "config.json"), "utf8"));
const schema = Bun.file(new URL(`./schemas/${name}.json`, import.meta.url));
const output = path.resolve(import.meta.dirname, "dist", "index.js");
```

Absolute paths and paths that come from a variable are fine:

{/* good */}
```js
import { readFileSync } from "node:fs";

readFileSync("/etc/hosts", "utf8");
readFileSync(process.argv[2], "utf8");
readFileSync(`${root}/config.json`, "utf8");
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `functions` | `[]` | Names of more functions that take a path as their first argument. A name matches both `loadFixture()` and `helpers.loadFixture()`. |

{/* bad {"count": 2, "options": [{"functions": ["loadFixture"]}]} */}
```js
const user = loadFixture("fixtures/user.json");
const team = helpers.loadFixture("fixtures/team.json");
```

## When not to use it

A command-line tool often means the working directory, like when it reads the `package.json` of the project it was started in. Say so with `process.cwd()`, or turn the rule off for those files:

{/* good */}
```js
import { readFileSync } from "node:fs";
import path from "node:path";

const manifest = readFileSync(path.resolve(process.cwd(), "package.json"), "utf8");
```
