# no-use-before-define

> Disallow using a variable, function, or class above the line that declares it

Reading a `let`, `const`, or `class` before its declaration runs throws a `ReferenceError`. Reading a `var` early gives `undefined` without any error. Function declarations do work before their line, but a reader has to scroll down to find out what's being called.

The rule goes by position in the file. A function that mentions a variable declared below it is reported, even if the function only runs later. The options relax that.

{/* 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]
"no-use-before-define" = "error" # or "warn"
```

Every option, set to its default:

```toml bunfig.toml
[lint.rules]
"no-use-before-define" = ["error", {
  functions = true,
  classes = true,
  variables = true,
  allowNamedExports = false,
  enums = true,
  typedefs = true,
  ignoreTypeReferences = true,
}]
```

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

## Examples

Reported:

{/* bad {"count": 3} */}
```js
console.log(limit);
const limit = 10;

start();
function start() {}

const total = total + 1;
```

{/* bad */}
```js
function report() {
  return limit;
}

const limit = 10;
```

Not reported:

{/* good */}
```js
const limit = 10;
console.log(limit);

function start() {}
start();
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `functions` | `true` | Report function declarations that are used early. |
| `classes` | `true` | With `false`, a function may mention a class that's declared below it. An early use in the same scope is still reported. |
| `variables` | `true` | The same as `classes`, for `var`, `let`, and `const`. |
| `allowNamedExports` | `false` | Allow `export { name }` above the declaration of `name`. |
| `enums` | `true` | Report TypeScript enums that are used early. |
| `typedefs` | `true` | Report type aliases and interfaces that are used early. |
| `ignoreTypeReferences` | `true` | Allow early uses in a type position, such as `let user: User` or `typeof config`. |

The string `"nofunc"` is short for `{ "functions": false }`.

With `functions: false`, you can call a function declaration early. It's already defined when the file starts to run:

{/* good {"options": [{"functions": false}]} */}
```js
start();

function start() {}
```

With `variables: false`, a function may mention a variable that's declared below it:

{/* good {"options": [{"variables": false}]} */}
```js
function report() {
  return limit;
}

const limit = 10;
```

An early use in the same scope runs before the declaration, so it's still reported:

{/* bad {"options": [{"variables": false}]} */}
```js
console.log(limit);
const limit = 10;
```

With `allowNamedExports: true`, you can keep the list of exports at the top of the file:

{/* good {"options": [{"allowNamedExports": true}]} */}
```js
export { limit };

const limit = 10;
```

Types don't exist when the code runs, so by default you can name a type before it's declared:

{/* good */}
```ts
let current: User;

interface User {
  name: string;
}
```

With `ignoreTypeReferences: false`, the same code is reported:

{/* bad {"options": [{"ignoreTypeReferences": false}]} */}
```ts
let current: User;

interface User {
  name: string;
}
```
