@drazenbebic/eslint-config-next 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +126 -0
- package/index.js +87 -0
- package/package.json +80 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Drazen Bebic
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# @drazenbebic/eslint-config-next
|
|
2
|
+
|
|
3
|
+
> Opinionated, shareable [ESLint flat config](https://eslint.org/docs/latest/use/configure/configuration-files) for personal Next.js projects.
|
|
4
|
+
|
|
5
|
+
It composes the official [`eslint-config-next`](https://www.npmjs.com/package/eslint-config-next) (Core Web Vitals + TypeScript) with Prettier, import sorting, unused-import removal, and [`perfectionist`](https://perfectionist.dev/) sorting — so a new Next.js app gets a consistent, batteries-included lint setup from a single dependency.
|
|
6
|
+
|
|
7
|
+
> **Heads up:** this is a personal config tuned to my own preferences. You're welcome to use it, but it will change to suit my projects, not yours. Pin a version if that matters to you.
|
|
8
|
+
|
|
9
|
+
## What's inside
|
|
10
|
+
|
|
11
|
+
- **`eslint-config-next/core-web-vitals`** and **`eslint-config-next/typescript`** — the official Next.js rules.
|
|
12
|
+
- **Prettier** via [`eslint-plugin-prettier`](https://github.com/prettier/eslint-plugin-prettier) (`prettier/prettier` runs as an ESLint rule, and conflicting stylistic rules are turned off by `eslint-config-prettier`).
|
|
13
|
+
- **`simple-import-sort`** — deterministic import/export ordering grouped as: side-effects → React/Next/node builtins → third-party → `@/` alias → relative.
|
|
14
|
+
- **`unused-imports`** — auto-removes unused imports and warns on unused vars.
|
|
15
|
+
- **`perfectionist`** — alphabetical sorting of JSX props, named imports/exports, union/intersection types, arrays, and more.
|
|
16
|
+
- A few hand-picked core rules: `no-console` (allowing `warn`/`error`), `curly: all`, and `padding-line-between-statements` (blank lines around `if`/`for`/`try`/`return`).
|
|
17
|
+
- Default ignores: `.next/**`, `out/**`, `build/**`, `next-env.d.ts`.
|
|
18
|
+
|
|
19
|
+
## Requirements
|
|
20
|
+
|
|
21
|
+
- **Node.js** `>= 20`
|
|
22
|
+
- **ESLint** `^9 || ^10` (flat config only — there is no `.eslintrc` support)
|
|
23
|
+
- **Next.js** (`next`) `>= 15` — already in your app; required because this config extends `eslint-config-next`, whose parser loads from `next`
|
|
24
|
+
- **Prettier** `^3`
|
|
25
|
+
- **TypeScript** `>= 5` (optional, only if your project uses it)
|
|
26
|
+
|
|
27
|
+
The ESLint plugins themselves ship as dependencies of this package, so you don't install them separately — only the peers above. In a real Next.js project `next` is already present, so you typically only add `eslint` and `prettier`.
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pnpm add -D @drazenbebic/eslint-config-next eslint prettier
|
|
33
|
+
# add typescript if your project uses it:
|
|
34
|
+
pnpm add -D typescript
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
<details>
|
|
38
|
+
<summary>npm / yarn</summary>
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install -D @drazenbebic/eslint-config-next eslint prettier typescript
|
|
42
|
+
# or
|
|
43
|
+
yarn add -D @drazenbebic/eslint-config-next eslint prettier typescript
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
</details>
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
Create an `eslint.config.mjs` (flat config) at the root of your project:
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
import config from '@drazenbebic/eslint-config-next';
|
|
54
|
+
|
|
55
|
+
export default config;
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
That's it. The default export is a flat-config array, so you can spread it and add your own overrides on top.
|
|
59
|
+
|
|
60
|
+
### Adding project-specific overrides
|
|
61
|
+
|
|
62
|
+
Because the config is a plain array, anything you add **after** the spread wins:
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
import { globalIgnores } from 'eslint/config';
|
|
66
|
+
|
|
67
|
+
import config from '@drazenbebic/eslint-config-next';
|
|
68
|
+
|
|
69
|
+
const eslintConfig = [
|
|
70
|
+
...config,
|
|
71
|
+
|
|
72
|
+
// Ignore generated files (e.g. Sanity TypeGen output).
|
|
73
|
+
globalIgnores(['sanity.types.ts']),
|
|
74
|
+
|
|
75
|
+
// Tweak or disable rules for your project.
|
|
76
|
+
{
|
|
77
|
+
rules: {
|
|
78
|
+
'no-console': 'off',
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
export default eslintConfig;
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
> **Note:** This config no longer ignores `sanity.types.ts` by default — add the `globalIgnores` line above in projects that use Sanity TypeGen.
|
|
87
|
+
|
|
88
|
+
### Prettier
|
|
89
|
+
|
|
90
|
+
`prettier/prettier` runs inside ESLint, so formatting issues show up as lint errors and are fixable with `eslint --fix`. Add your own `.prettierrc` to control formatting (this config does not impose a Prettier style on your project). A typical `package.json`:
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"scripts": {
|
|
95
|
+
"lint": "next lint",
|
|
96
|
+
"lint:fix": "eslint . --fix"
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### The `@/` import group
|
|
102
|
+
|
|
103
|
+
The import-sort rules put imports matching `^@/` in their own group, which assumes you use the `@/*` path alias (the Next.js default). If you use a different alias, override `simple-import-sort/imports` in your project config.
|
|
104
|
+
|
|
105
|
+
## Releasing (maintainer notes)
|
|
106
|
+
|
|
107
|
+
This package uses [release-please](https://github.com/googleapis/release-please) with **Conventional Commits**. Versions, the changelog, and the GitHub release are derived from commit messages on `main`:
|
|
108
|
+
|
|
109
|
+
- `feat: …` → minor bump
|
|
110
|
+
- `fix: …` / `perf: …` → patch bump
|
|
111
|
+
- `feat!: …` or a `BREAKING CHANGE:` footer → major bump (minor while pre-1.0)
|
|
112
|
+
|
|
113
|
+
When release-please's "Version Packages" PR is merged, the `release-please` workflow publishes to npm with [provenance](https://docs.npmjs.com/generating-provenance-statements) using [npm trusted publishing](https://docs.npmjs.com/trusted-publishers) (OIDC) — there is no long-lived `NPM_TOKEN` secret to manage.
|
|
114
|
+
|
|
115
|
+
**One-time bootstrap** (because npm can only attach a trusted publisher to a package that already exists):
|
|
116
|
+
|
|
117
|
+
1. Publish once manually to claim the name and create the package:
|
|
118
|
+
```bash
|
|
119
|
+
npm publish --access public
|
|
120
|
+
```
|
|
121
|
+
2. On npmjs.com → the package's **Settings → Trusted Publisher**, add this repo's GitHub Actions workflow (`.github/workflows/release-please.yml`).
|
|
122
|
+
3. From then on, merging the release-please PR publishes hands-free via OIDC.
|
|
123
|
+
|
|
124
|
+
## License
|
|
125
|
+
|
|
126
|
+
[MIT](./LICENSE)
|
package/index.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { defineConfig, globalIgnores } from 'eslint/config';
|
|
2
|
+
import nextVitals from 'eslint-config-next/core-web-vitals';
|
|
3
|
+
import nextTs from 'eslint-config-next/typescript';
|
|
4
|
+
import pluginPerfectionist from 'eslint-plugin-perfectionist';
|
|
5
|
+
import prettierRecommended from 'eslint-plugin-prettier/recommended';
|
|
6
|
+
import simpleImportSort from 'eslint-plugin-simple-import-sort';
|
|
7
|
+
import pluginUnusedImports from 'eslint-plugin-unused-imports';
|
|
8
|
+
|
|
9
|
+
const PERFECTIONIST_DEFAULT_ARGS = {
|
|
10
|
+
type: 'alphabetical',
|
|
11
|
+
order: 'asc',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const PERFECTIONIST_DEFAULT_CONFIG = ['error', PERFECTIONIST_DEFAULT_ARGS];
|
|
15
|
+
|
|
16
|
+
const eslintConfig = defineConfig([
|
|
17
|
+
...nextVitals,
|
|
18
|
+
...nextTs,
|
|
19
|
+
prettierRecommended,
|
|
20
|
+
{
|
|
21
|
+
settings: {
|
|
22
|
+
react: {
|
|
23
|
+
version: '19',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
plugins: {
|
|
27
|
+
perfectionist: pluginPerfectionist,
|
|
28
|
+
'unused-imports': pluginUnusedImports,
|
|
29
|
+
'simple-import-sort': simpleImportSort,
|
|
30
|
+
},
|
|
31
|
+
rules: {
|
|
32
|
+
'prettier/prettier': 'error',
|
|
33
|
+
'unused-imports/no-unused-imports': 'warn',
|
|
34
|
+
'unused-imports/no-unused-vars': 'warn',
|
|
35
|
+
'no-console': ['warn', { allow: ['warn', 'error'] }],
|
|
36
|
+
curly: ['error', 'all'],
|
|
37
|
+
'padding-line-between-statements': [
|
|
38
|
+
'error',
|
|
39
|
+
{ blankLine: 'always', prev: '*', next: 'if' },
|
|
40
|
+
{ blankLine: 'always', prev: 'if', next: '*' },
|
|
41
|
+
{ blankLine: 'always', prev: '*', next: 'for' },
|
|
42
|
+
{ blankLine: 'always', prev: 'for', next: '*' },
|
|
43
|
+
{ blankLine: 'always', prev: '*', next: 'try' },
|
|
44
|
+
{ blankLine: 'always', prev: 'try', next: '*' },
|
|
45
|
+
{ blankLine: 'always', prev: '*', next: 'return' },
|
|
46
|
+
],
|
|
47
|
+
'simple-import-sort/exports': 'error',
|
|
48
|
+
'simple-import-sort/imports': [
|
|
49
|
+
'error',
|
|
50
|
+
{
|
|
51
|
+
groups: [
|
|
52
|
+
// 1. Side effect imports (e.g. import 'style.css')
|
|
53
|
+
['^\\u0000'],
|
|
54
|
+
// 2. React, Next.js, and other node built-ins
|
|
55
|
+
['^react', '^next', '^node:'],
|
|
56
|
+
// 3. Third-party packages (starting with a letter or @)
|
|
57
|
+
['^@?\\w'],
|
|
58
|
+
// 4. Internal imports (using your @/ alias)
|
|
59
|
+
['^@/'],
|
|
60
|
+
// 5. Relative imports (starting with .)
|
|
61
|
+
['^\\.'],
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
'perfectionist/sort-jsx-props': PERFECTIONIST_DEFAULT_CONFIG,
|
|
66
|
+
'perfectionist/sort-exports': PERFECTIONIST_DEFAULT_CONFIG,
|
|
67
|
+
'perfectionist/sort-named-exports': PERFECTIONIST_DEFAULT_CONFIG,
|
|
68
|
+
'perfectionist/sort-named-imports': PERFECTIONIST_DEFAULT_CONFIG,
|
|
69
|
+
'perfectionist/sort-intersection-types': PERFECTIONIST_DEFAULT_CONFIG,
|
|
70
|
+
'perfectionist/sort-array-includes': PERFECTIONIST_DEFAULT_CONFIG,
|
|
71
|
+
'perfectionist/sort-union-types': PERFECTIONIST_DEFAULT_CONFIG,
|
|
72
|
+
'perfectionist/sort-arrays': [
|
|
73
|
+
'error',
|
|
74
|
+
{
|
|
75
|
+
...PERFECTIONIST_DEFAULT_ARGS,
|
|
76
|
+
useConfigurationIf: {
|
|
77
|
+
matchesAstSelector: 'TSAsExpression > ArrayExpression',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
// Default ignores carried over from eslint-config-next.
|
|
84
|
+
globalIgnores(['.next/**', 'out/**', 'build/**', 'next-env.d.ts']),
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
export default eslintConfig;
|
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@drazenbebic/eslint-config-next",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Opinionated, shareable ESLint flat config for personal Next.js projects (Next + TypeScript + Prettier + import sorting + perfectionist).",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"eslint",
|
|
7
|
+
"eslintconfig",
|
|
8
|
+
"eslint-config",
|
|
9
|
+
"eslintconfig-next",
|
|
10
|
+
"next",
|
|
11
|
+
"nextjs",
|
|
12
|
+
"react",
|
|
13
|
+
"typescript",
|
|
14
|
+
"prettier",
|
|
15
|
+
"perfectionist",
|
|
16
|
+
"flat-config"
|
|
17
|
+
],
|
|
18
|
+
"homepage": "https://github.com/drazenbebic/eslint-config-next#readme",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/drazenbebic/eslint-config-next/issues"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/drazenbebic/eslint-config-next.git"
|
|
25
|
+
},
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"author": {
|
|
28
|
+
"name": "Drazen Bebic",
|
|
29
|
+
"email": "drazen.bebic@outlook.com",
|
|
30
|
+
"url": "https://www.bebic.dev"
|
|
31
|
+
},
|
|
32
|
+
"type": "module",
|
|
33
|
+
"exports": {
|
|
34
|
+
".": "./index.js"
|
|
35
|
+
},
|
|
36
|
+
"main": "./index.js",
|
|
37
|
+
"sideEffects": false,
|
|
38
|
+
"files": [
|
|
39
|
+
"index.js"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"lint": "eslint .",
|
|
43
|
+
"lint:fix": "eslint . --fix",
|
|
44
|
+
"format": "prettier --write .",
|
|
45
|
+
"format:check": "prettier --check .",
|
|
46
|
+
"test": "node --test"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"eslint-config-next": "^16.2.9",
|
|
50
|
+
"eslint-config-prettier": "^10.1.8",
|
|
51
|
+
"eslint-plugin-perfectionist": "^5.9.1",
|
|
52
|
+
"eslint-plugin-prettier": "^5.5.6",
|
|
53
|
+
"eslint-plugin-simple-import-sort": "^13.0.0",
|
|
54
|
+
"eslint-plugin-unused-imports": "^4.4.1"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"eslint": "^9.0.0 || ^10.0.0",
|
|
58
|
+
"next": ">=15.0.0",
|
|
59
|
+
"prettier": "^3.0.0",
|
|
60
|
+
"typescript": ">=5.0.0"
|
|
61
|
+
},
|
|
62
|
+
"peerDependenciesMeta": {
|
|
63
|
+
"typescript": {
|
|
64
|
+
"optional": true
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"eslint": "^10.6.0",
|
|
69
|
+
"next": "^16.2.9",
|
|
70
|
+
"prettier": "^3.9.0",
|
|
71
|
+
"typescript": "^6.0.3"
|
|
72
|
+
},
|
|
73
|
+
"engines": {
|
|
74
|
+
"node": ">=20"
|
|
75
|
+
},
|
|
76
|
+
"publishConfig": {
|
|
77
|
+
"access": "public"
|
|
78
|
+
},
|
|
79
|
+
"packageManager": "pnpm@11.5.2"
|
|
80
|
+
}
|