# new-cap

> Require constructor names to begin with a capital letter

A capital first letter is how you tell a constructor from an ordinary function. If names don't follow that convention, it's easy to forget `new`. A class then throws, and an older constructor function runs with the wrong `this`.

The rule reports two things: `new` with a name that starts with a lowercase letter, and a call without `new` to a name that starts with a capital letter.

The built-ins that work without `new` are allowed: `Array`, `BigInt`, `Boolean`, `Date`, `Error`, `Function`, `Number`, `Object`, `RegExp`, `String`, `Symbol`, and `Date.UTC()`.

{/* 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]
"new-cap" = "error" # or "warn"
```

Every option, set to its default. The ones that are commented out are unset by default.

```toml bunfig.toml
[lint.rules]
"new-cap" = ["error", {
  newIsCap = true,
  capIsNew = true,
  properties = true,
  newIsCapExceptions = [], # list of strings
  # newIsCapExceptionPattern = <string>,
  capIsNewExceptions = [], # list of strings
  # capIsNewExceptionPattern = <string>,
}]
```

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

## Examples

Reported:

{/* bad {"count": 2} */}
```js
const user = new person("Ada");
const team = Team("core");
```

Not reported:

{/* good */}
```js
const user = new Person("Ada");
const team = createTeam("core");
const id = String(42);
const start = Date.UTC(2026, 0, 1);
```

## Options

```toml bunfig.toml
[lint.rules]
new-cap = ["error", { capIsNewExceptions = ["Router"] }]
```

| Option | Default | What it does |
| --- | --- | --- |
| `newIsCap` | `true` | Report `new` with a lowercase name. |
| `capIsNew` | `true` | Report a call to a capitalized name without `new`. |
| `properties` | `true` | Also check names after a dot, as in `new net.socket()` and `express.Router()`. |
| `newIsCapExceptions` | `[]` | Lowercase names that are allowed after `new`. |
| `newIsCapExceptionPattern` | none | A regular expression for those names. |
| `capIsNewExceptions` | `[]` | Capitalized names that can be called without `new`. |
| `capIsNewExceptionPattern` | none | A regular expression for those names. |

Reported by default:

{/* bad */}
```js
const router = express.Router();
```

Not reported with `capIsNewExceptions: ["Router"]`. `"express.Router"` works too:

{/* good {"options": [{"capIsNewExceptions": ["Router"]}]} */}
```js
const router = express.Router();
```

A pattern is tested against the whole `express.Router`. Not reported with `capIsNewExceptionPattern: "^express\\."`:

{/* good {"options": [{"capIsNewExceptionPattern": "^express\\."}]} */}
```js
const router = express.Router();
```

Not reported with `newIsCapExceptions: ["moment"]`:

{/* good {"options": [{"newIsCapExceptions": ["moment"]}]} */}
```js
const now = new moment();
```

Not reported with `properties: false`:

{/* good {"options": [{"properties": false}]} */}
```js
const router = express.Router();
const socket = new net.socket();
```

## When not to use it

Some libraries export capitalized functions that are meant to be called without `new`. If you use many of them, set `capIsNew` to `false`.
