# n/no-unsupported-features/es-syntax

> Disallow JavaScript syntax that the Node.js versions you support do not have

Syntax that's newer than the oldest Node.js you support is a `SyntaxError` there, so the file doesn't load at all. You only find out when somebody runs it on that version.

The rule takes the versions you support from `engines.node` in your `package.json`. If nothing sets a range, it assumes `>=16.0.0`. Every version in the range must have the feature.

Besides syntax, it reports newer built-ins such as `Object.hasOwn`, and newer methods such as `.at()` when the code shows they're called on an array or a string.

{/* 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]
"n/no-unsupported-features/es-syntax" = "error" # or "warn"
```

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

```toml bunfig.toml
[lint.rules]
"n/no-unsupported-features/es-syntax" = ["error", {
  # version = <string>,
  ignores = [], # list of strings
}]
```

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

## Examples

Reported, because Node.js has had static blocks since 16.11.0 and the `v` flag since 20.0.0:

{/* bad {"count": 2} */}
```js
class Cache {
  static instance;
  static {
    Cache.instance = new Cache();
  }
}

const word = /[\p{L}--[a-z]]/v;
```

Not reported:

{/* good */}
```js
class Cache {
  static instance = new Cache();
}

const word = /\p{L}/u;
```

With a newer `engines.node`, static blocks are fine:

{/* file "package.json" */}
```json
{
  "name": "app",
  "engines": { "node": ">=18.0.0" }
}
```

{/* good */}
```js
class Cache {
  static instance;
  static {
    Cache.instance = new Cache();
  }
}
```

A method is reported if the rule can tell that the value is an array or a string:

{/* bad */}
```js
const steps = ["build", "test", "publish"];
const last = steps.at(-1);
```

{/* good */}
```js
function lastOf(steps) {
  return steps.at(-1);
}
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `version` | `engines.node`, or `">=16.0.0"` | The range of Node.js versions you support, written as in `package.json`. |
| `ignores` | `[]` | Features that are never reported, by the name in the message, such as `"class-static-block"`. |

Without `version`, the range comes from `settings.n.version` (`[lint.settings.n]` in `bunfig.toml`, or `settings` in an ESLint config), then from `engines.node`, then from `devEngines.runtime` in `package.json`.

```toml bunfig.toml
[lint.rules]
"n/no-unsupported-features/es-syntax" = ["error", {
  version = ">=14.0.0",
  ignores = ["logical-assignment-operators"],
}]
```

{/* bad {"options": [{"version": ">=14.0.0"}]} */}
```js
options.retries ??= 3;
```

{/* good {"options": [{"version": ">=15.0.0"}]} */}
```js
options.retries ??= 3;
```

{/* good {"options": [{"version": ">=14.0.0", "ignores": ["logical-assignment-operators"]}]} */}
```js
options.retries ??= 3;
```

## When not to use it

If you compile the code for the versions you target before it runs, with TypeScript or a bundler, the source can use any syntax.
