Skip to content

Commit 1180f59

Browse files
authored
feat: Remove ESLint package support (#50)
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> BREAKING CHANGE: Remove ESLint config
1 parent 9f98897 commit 1180f59

19 files changed

Lines changed: 1183 additions & 3796 deletions

.github/DISCUSSION_TEMPLATE/eslint-suggestion.yml

Lines changed: 0 additions & 64 deletions
This file was deleted.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
body:
2+
- type: markdown
3+
attributes:
4+
value: |-
5+
Thank you for helping to improve `@epic-web/config`!
6+
7+
Please fill out the details below.
8+
9+
Keep in mind you can always extend the built-in configuration with your own config.
10+
- type: textarea
11+
attributes:
12+
label: Search Terms Used
13+
description: >-
14+
Please list the search terms you used to search the discussions, issues,
15+
and PRs before submitting this issue.
16+
validations:
17+
required: true
18+
- type: input
19+
attributes:
20+
label: Rule or Config Docs
21+
description: >-
22+
Link to the Oxlint rule or configuration docs you're suggesting
23+
changing
24+
placeholder: https://oxc.rs/docs/guide/usage/linter/rules/
25+
validations:
26+
required: true
27+
- type: textarea
28+
attributes:
29+
label: Suggested Change
30+
description: >-
31+
Write out the suggested change in configuration. If the rule or config is
32+
already present, explain why it should be removed or changed. If it's not
33+
present, explain why it should be added. And provide the final
34+
configuration for the option.
35+
validations:
36+
required: true
37+
- type: textarea
38+
attributes:
39+
label: Issues without the change
40+
description: >-
41+
Convince me why life is better with this change.
42+
validations:
43+
required: true
44+
- type: textarea
45+
attributes:
46+
label: Severity of inaction
47+
description: Convince me why not doing anything is bad.
48+
validations:
49+
required: true
50+
- type: textarea
51+
attributes:
52+
label: Additional Context
53+
description: Any other context that could be helpful.
54+
validations:
55+
required: false

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ contact_links:
55
about:
66
If you can't get something to work the way you expect, open a question in
77
the discussions.
8-
- name: 👮 ESLint Rule Suggestion
9-
url: https://github.com/epicweb-dev/config/discussions/new?category=eslint-suggestion
8+
- name: 🐂 Oxlint Rule Suggestion
9+
url: https://github.com/epicweb-dev/config/discussions/new?category=oxlint-suggestion
1010
about:
1111
We appreciate you taking the time to improve `@epic-web/config` with your
12-
ideas, but we use the Discussions for this instead of the issues tab 🙂.
12+
ideas, but we use Discussions for config suggestions instead of the issues
13+
tab.
1314
- name: 💬 Epic Web Discord Server
1415
url: https://kcd.im/discord
1516
about: Interact with other Epic Web developers

README.md

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<div>
22
<h1 align="center"><a href="https://npm.im/@epic-web/config">👮 @epic-web/config</a></h1>
33
<strong>
4-
Reasonable ESLint, Oxlint, Prettier, and TypeScript configs for epic web devs
4+
Reasonable Oxlint, Prettier, and TypeScript configs for epic web devs
55
</strong>
66
<p>
77
This makes assumptions about the way you prefer to develop software and gives you configurations that will actually help you in your development.
@@ -40,8 +40,11 @@ configuring code quality tools or babysitting them.
4040

4141
## This solution
4242

43-
This is a set of configurations you can use in your web projects to avoid
44-
wasting time.
43+
This package provides shared defaults for the tools this repo currently ships:
44+
45+
- Oxlint
46+
- Prettier
47+
- TypeScript
4548

4649
## Decisions
4750

@@ -114,33 +117,6 @@ Learn more from
114117

115118
</details>
116119

117-
### ESLint
118-
119-
Create a `eslint.config.js` file in your project root with the following
120-
content:
121-
122-
```js
123-
import { config as defaultConfig } from '@epic-web/config/eslint'
124-
125-
/** @type {import("eslint").Linter.Config[]} */
126-
export default [...defaultConfig]
127-
```
128-
129-
<details>
130-
<summary>Customizing ESLint</summary>
131-
132-
Learn more from
133-
[the Eslint docs here](https://eslint.org/docs/latest/extend/shareable-configs#overriding-settings-from-shareable-configs).
134-
135-
</details>
136-
137-
There are endless rules we could enable. However, we want to keep our
138-
configurations minimal and only enable rules that catch real problems (the kind
139-
that are likely to happen). This keeps our linting faster and reduces the number
140-
of false positives.
141-
142-
Custom rule documentation lives in [`lint-rules/index.md`](./lint-rules/index.md).
143-
144120
### Oxlint
145121

146122
Create a `.oxlintrc.json` file in your project root with the following content:
@@ -151,22 +127,28 @@ Create a `.oxlintrc.json` file in your project root with the following content:
151127
}
152128
```
153129

130+
This config includes the custom `epic-web/*` rules documented in
131+
[`lint-rules/index.md`](./lint-rules/index.md).
132+
154133
Note: `typescript/no-misused-promises` and `typescript/no-floating-promises` are
155134
type-aware in Oxlint and require the type-aware setup described in the Oxlint
156135
docs.
157136

158-
#### Unsupported rules
137+
Some Oxlint rule IDs still use the `eslint/` namespace because that is how
138+
Oxlint exposes those compatibility rules. You do not need to install ESLint to
139+
use them.
140+
141+
#### Not yet covered
159142

160-
The following ESLint rules/plugins from this config are not yet available in
161-
Oxlint, so they are intentionally omitted:
143+
The following rule families are intentionally omitted because they are not yet
144+
part of the Oxlint config this package ships:
162145

163146
- `import/order`
164147
- `react-hooks/rules-of-hooks`
165148
- `react-hooks/exhaustive-deps`
166-
- `@typescript-eslint/no-unused-vars` (falls back to `eslint/no-unused-vars`)
167149
- `testing-library/*`
168150
- `jest-dom/*`
169-
- `vitest/*` (except `vitest/no-import-node-test`)
151+
- most `vitest/*` rules
170152
- `playwright/*`
171153

172154
## License
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Move to Oxlint
2+
3+
Date: 2026-03-26
4+
5+
Status: accepted
6+
7+
## Context
8+
9+
This package originally shipped both ESLint and Oxlint configuration. Over time,
10+
the Oxlint side of the package became the simpler path to maintain and consume.
11+
12+
There are a few reasons for that:
13+
14+
1. Oxlint is dramatically faster, which makes local feedback and CI validation
15+
cheaper.
16+
2. The configuration story is simpler when we only ship one linting toolchain.
17+
3. The Oxlint project has an active and clearly invested team behind it, which
18+
makes it a good foundation to build on.
19+
4. Oxlint's compatibility with many established ESLint rule IDs makes migration
20+
straightforward, so moving away from ESLint does not require a wholesale
21+
rethink of the existing rule set.
22+
23+
Because Oxlint can consume many familiar `eslint/...` rule identifiers and we
24+
already author our custom rules as Oxlint JS plugins, the migration path is
25+
mostly about removing duplicate package surface rather than redesigning the
26+
linting rules themselves.
27+
28+
## Decision
29+
30+
Ship Oxlint as the package's linting solution and remove the published ESLint
31+
configs, ESLint plugin entry points, and ESLint package dependencies.
32+
33+
## Consequences
34+
35+
- Consumers must migrate from the removed ESLint entry points to the Oxlint
36+
config.
37+
- Some rule IDs may continue to use the `eslint/` namespace inside Oxlint
38+
config, because that is how Oxlint exposes compatibility rules.
39+
- The package becomes smaller and easier to maintain because it only supports a
40+
single linting toolchain.
41+
- Linting should be faster for both maintainers and consumers.

docs/style-guide.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,10 +1073,9 @@ function calculateTotal(items: Array<number>) {
10731073

10741074
Don't use semicolons. The rules for when you should use semicolons are more
10751075
complicated than the rules for when you must use semicolons. With the right
1076-
eslint rule
1077-
([`no-unexpected-multiline`](https://eslint.org/docs/latest/rules/no-unexpected-multiline))
1078-
and a formatter that will format your code funny for you if you mess up, you can
1079-
avoid the pitfalls. Read more about this in
1076+
Oxlint rule (`eslint/no-unexpected-multiline`) and a formatter that will format
1077+
your code funny for you if you mess up, you can avoid the pitfalls. Read more
1078+
about this in
10801079
[Semicolons in JavaScript: A preference](https://kentcdodds.com/blog/semicolons-in-javascript-a-preference).
10811080

10821081
<!-- prettier-ignore -->
@@ -1826,7 +1825,7 @@ test('Form shows error for invalid email', async () => {
18261825

18271826
Prioritize your tests according to the Testing Trophy:
18281827

1829-
1. Static Analysis (TypeScript, ESLint)
1828+
1. Static Analysis (TypeScript, Oxlint)
18301829
2. Unit Tests (Pure Functions)
18311830
3. Integration Tests (Component Integration)
18321831
4. E2E Tests (Critical User Flows)

eslint-plugin-epic-web.js

Lines changed: 0 additions & 3 deletions
This file was deleted.

eslint.config.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)