oxlint-plugin-arch 0.2.4 → 0.3.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/CHANGELOG.md +20 -0
- package/README.md +264 -66
- package/dist/index.js +2498 -257
- package/package.json +4 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
- Add `no-promise-all-mutation`, `no-literal-in`, and `test-title-pattern` to replace hand-written `no-restricted-syntax` selectors with scope-aware, configurable rules.
|
|
6
|
+
- Add `no-module-mutable-state`, `no-restricted-constructor`, and `no-comments` (directives, bundler annotations, and `Why:` comments kept; one-pass autofix that skips JSX comments and directive-adjacent lines).
|
|
7
|
+
- Add layout rules `padding-between-statements`, `object-multiline`, `key-value-same-line`, `chain-newline`, `call-array-multiline`, and `jsx-attributes-multiline`. Fixes only change whitespace and are skipped when comments or unusual syntax make them unsafe.
|
|
8
|
+
- Extend `no-extra-exports` with regex `patterns`, `no-restricted-token` with multiple `restrictions` and `member` matching, and `require-paired-call` with `pairs`.
|
|
9
|
+
- Extend `require-object-params` with `maxParams`, `allDeclarations`, and `allowPattern`; `only-export-components` with `allowTypeExports` and `denyTypePattern`; and `no-extra-factory-keys` with `requireKeys` and `keySets`.
|
|
10
|
+
- Extend `no-runtime-in-types` with opt-in `runtimeImports`, `allowImportSources`, and `banReExports`; `no-trivial-functions` with `allowCallees` and `allowAsync`; and `no-inline-types` with `minMembers`.
|
|
11
|
+
- All option changes are backward compatible; existing configs keep today's behavior.
|
|
12
|
+
- Speed up `declaration-name`, `no-type-declarations`, `no-inline-types`, and `no-promise-all-mutation` by using native visitors and per-file option setup instead of whole-AST JavaScript walks.
|
|
13
|
+
- Add `examples/monorepo.oxlint.config.ts`, a strict copy-ready config for `apps/server` + `apps/web` monorepos.
|
|
14
|
+
- Remove the `install-oxlint-arch` agent skill and vendored copy; install the npm package instead.
|
|
15
|
+
|
|
16
|
+
## 0.2.5
|
|
17
|
+
|
|
18
|
+
- Add `no-inline-types` to require named object and function types in function signatures, with separate parameter, return, and function-type options.
|
|
19
|
+
- Add `only-export-constants` to restrict exports to local `const` bindings, with opt-ins for function values, type exports, and re-exports.
|
|
20
|
+
- Add `no-member-comments` to remove comments on object/type members while preserving directives and optional `Why:` explanations.
|
|
21
|
+
- Document the new rule options and syntax-only limits, extend the full configuration example to all 30 rules, and sync the optional vendored skill assets.
|
|
22
|
+
|
|
3
23
|
## 0.2.4
|
|
4
24
|
|
|
5
25
|
- Add `trailingRoles` and `roleSeparators` so `export-file-prefix`, `declaration-name`, and `no-extra-exports` can treat `onchain-utils.ts` like `onchain.utils.ts`.
|
package/README.md
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
|
-
# oxlint-plugin-arch
|
|
1
|
+
# 🏛️ oxlint-plugin-arch
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Architecture rules for [Oxlint](https://oxc.rs), driven by filenames and fully configurable.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Keep a codebase shaped the way you designed it: files in the right folders, exports named after their file, types where they belong, and no shortcuts across boundaries. Every rule is generic, so **you** decide the paths, names, and policy in your own Oxlint config.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- 🗂️ **Filename-aware.** Rules derive expected names from the file they run on (`user-action.create.ts` → `makeUserActionCreate`).
|
|
8
|
+
- 🎛️ **Configurable.** No app names, folders, or libraries are baked in. Globs and policy live in your config.
|
|
9
|
+
- 🛟 **Safe autofix.** Fixable rules only touch whitespace or comments, and never guess when a fix could change your code.
|
|
10
|
+
- ⚡ **Fast.** Built on Oxlint's JS plugin API and ESTree, with no extra parser.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 📦 Install
|
|
8
15
|
|
|
9
16
|
```bash
|
|
10
17
|
bun add -d oxlint-plugin-arch oxlint @oxlint/plugins
|
|
11
18
|
```
|
|
12
19
|
|
|
13
|
-
|
|
20
|
+
> [!NOTE]
|
|
21
|
+
> Keep `oxlint` and `@oxlint/plugins` on matching versions.
|
|
22
|
+
|
|
23
|
+
Register the plugin in `oxlint.config.ts`:
|
|
14
24
|
|
|
15
25
|
```ts
|
|
16
26
|
import { defineConfig } from 'oxlint'
|
|
@@ -22,82 +32,270 @@ export default defineConfig({
|
|
|
22
32
|
})
|
|
23
33
|
```
|
|
24
34
|
|
|
25
|
-
##
|
|
35
|
+
## 🚀 Quick start
|
|
26
36
|
|
|
27
|
-
|
|
37
|
+
Rules are switched on per folder with `overrides`. Here are three small ones:
|
|
28
38
|
|
|
29
|
-
|
|
39
|
+
```ts
|
|
40
|
+
export default defineConfig({
|
|
41
|
+
jsPlugins: [{ name: 'arch', specifier: 'oxlint-plugin-arch' }],
|
|
42
|
+
rules: {
|
|
43
|
+
'arch/no-literal-in': 'error',
|
|
44
|
+
},
|
|
45
|
+
overrides: [
|
|
46
|
+
{
|
|
47
|
+
files: ['**/src/components/**/*.tsx'],
|
|
48
|
+
rules: {
|
|
49
|
+
'arch/only-export-components': ['error', { matchFileName: true }],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
files: ['**/*.test.ts'],
|
|
54
|
+
rules: {
|
|
55
|
+
'arch/test-title-pattern': ['error', { forbid: '^should\\b', flags: 'i' }],
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
})
|
|
60
|
+
```
|
|
30
61
|
|
|
31
|
-
##
|
|
62
|
+
## 📚 Examples
|
|
32
63
|
|
|
33
|
-
|
|
64
|
+
| File | Use it when |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| [`minimal.oxlint.config.ts`](examples/minimal.oxlint.config.ts) | You want the smallest possible starting point. |
|
|
67
|
+
| [`monorepo.oxlint.config.ts`](examples/monorepo.oxlint.config.ts) | ⭐ You are starting an `apps/server` + `apps/web` monorepo and want a strict, copy-ready setup. |
|
|
68
|
+
| [`full.oxlint.config.ts`](examples/full.oxlint.config.ts) | You want to see every one of the 42 rules with its options. |
|
|
34
69
|
|
|
35
|
-
|
|
36
|
-
|
|
70
|
+
> [!TIP]
|
|
71
|
+
> `monorepo.oxlint.config.ts` already loads `oxlint-plugin-arch`, so you can copy it as-is and adjust globs and names. The other two load `../src/index.ts`; change that specifier to `oxlint-plugin-arch` when you copy them.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 🧩 Rules
|
|
76
|
+
|
|
77
|
+
42 rules in 9 groups. 🔧 means the rule can autofix. Each rule file in [`src/rules/`](src/rules) explains its behavior in plain English, and the tests in [`src/tests/`](src/tests) show every option shape.
|
|
78
|
+
|
|
79
|
+
### 📁 Files & folders
|
|
80
|
+
|
|
81
|
+
| Rule | What it enforces |
|
|
82
|
+
| --- | --- |
|
|
83
|
+
| `filename-match` | Filenames match a pattern you configure. |
|
|
84
|
+
| `folder-prefix` | Filenames start with their parent folder name, or the folders after a root you choose. |
|
|
85
|
+
| `no-restricted-files` | Files matching a glob you forbid are reported, for example misplaced `*.types.ts`. |
|
|
86
|
+
|
|
87
|
+
### 🏷️ Naming & exports
|
|
88
|
+
|
|
89
|
+
| Rule | What it enforces |
|
|
90
|
+
| --- | --- |
|
|
91
|
+
| `declaration-name` | Selected declarations start with a prefix taken from the filename, or match a pattern. |
|
|
92
|
+
| `export-file-prefix` | Export names (or every function and type) start with the filename prefix. `trailingRoles` treats `onchain-utils.ts` like `onchain.utils.ts`. |
|
|
93
|
+
| `export-name-pattern` | Export names (or every function and type) match a regular expression. |
|
|
94
|
+
| `filename-export-name` | Function names follow a template built from the filename. |
|
|
95
|
+
| `no-extra-exports` | A file exports only the names you allow. `patterns` accepts families such as `{Domain}[A-Z]\w*`. |
|
|
96
|
+
| `only-export-constants` | Constant files export only local `const` values. [Details ↓](#only-export-constants) |
|
|
97
|
+
|
|
98
|
+
### 🏭 Functions & factories
|
|
99
|
+
|
|
100
|
+
| Rule | What it enforces |
|
|
101
|
+
| --- | --- |
|
|
102
|
+
| `require-file-factory` | The file defines the factory function its filename promises. |
|
|
103
|
+
| `no-extra-factory-keys` | A factory returns only allowed keys. `requireKeys` makes keys mandatory; `keySets` sets keys per factory pattern. |
|
|
104
|
+
| `require-object-params` | Functions take object parameters instead of long positional lists. `maxParams: 2` allows `(deps, params)`. |
|
|
105
|
+
| `no-file-level-helpers` | No stray helper functions at module scope. |
|
|
106
|
+
| `no-top-level-functions` | No top-level functions (and optionally no re-exports) in matched files. |
|
|
107
|
+
| `no-trivial-functions` | No empty or pass-through wrapper functions. `allowCallees` keeps intentional wrappers. |
|
|
108
|
+
| `no-module-mutable-state` | No module-level `let`/`var`, which is shared across requests and tests. |
|
|
109
|
+
|
|
110
|
+
### 🔷 Types
|
|
111
|
+
|
|
112
|
+
| Rule | What it enforces |
|
|
113
|
+
| --- | --- |
|
|
114
|
+
| `no-inline-types` | Function signatures use named types instead of inline `{ ... }` objects. [Details ↓](#no-inline-types) |
|
|
115
|
+
| `no-type-declarations` | No type aliases or interfaces in matched files, so types live in one place. |
|
|
116
|
+
| `no-runtime-in-types` | Type modules stay free of runtime code. Opt in to also ban runtime imports and re-exports. |
|
|
117
|
+
| `no-imported-type-alias` | No exported aliases that only rename an imported type. |
|
|
118
|
+
|
|
119
|
+
### 🧪 Schemas & APIs
|
|
120
|
+
|
|
121
|
+
| Rule | What it enforces |
|
|
122
|
+
| --- | --- |
|
|
123
|
+
| `no-local-schema-construction` | No schemas built outside the files that own them. |
|
|
124
|
+
| `no-inline-schema-elements` | Named schemas inside combinators like `z.array(...)`. |
|
|
125
|
+
| `no-rederive-schema` | No re-deriving types from schemas imported from elsewhere. |
|
|
126
|
+
| `no-single-use-scalar-schema` | Scalar Zod aliases used once get inlined. |
|
|
127
|
+
| `require-orpc-output` | oRPC procedures declare a named `.output()` schema. |
|
|
128
|
+
| `no-unescaped-like` | `LIKE` / `ILIKE` values pass through your sanitizer. |
|
|
129
|
+
|
|
130
|
+
### 🚧 Boundaries & safety
|
|
131
|
+
|
|
132
|
+
| Rule | What it enforces |
|
|
133
|
+
| --- | --- |
|
|
134
|
+
| `no-restricted-token` | Identifiers or member calls appear only in owner files. `member: '*.insertInto'` keeps writes out of query files. [Details ↓](#no-restricted-token) |
|
|
135
|
+
| `no-restricted-constructor` | No `new Error()` (or any constructor you list) where typed errors are required. |
|
|
136
|
+
| `require-paired-call` | Calling one function requires calling another, for example `useForm` with a schema resolver. |
|
|
137
|
+
| `no-promise-all-mutation` | No `results.push(...)` or `total += x` on outer variables inside `Promise.all`. Return values instead. |
|
|
138
|
+
| `no-literal-in` | No `'key' in value`. Use `Object.hasOwn()` or a discriminated union. |
|
|
139
|
+
|
|
140
|
+
### ⚛️ React
|
|
141
|
+
|
|
142
|
+
| Rule | What it enforces |
|
|
143
|
+
| --- | --- |
|
|
144
|
+
| `only-export-components` | Component files export only components. `denyTypePattern: 'Props$'` keeps props private. |
|
|
145
|
+
| `route-surface` | Route files export the route only, with no banned hooks or raw JSX. |
|
|
146
|
+
|
|
147
|
+
### 💬 Comments & tests
|
|
148
|
+
|
|
149
|
+
| Rule | What it enforces |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| `no-comments` 🔧 | No comments in matched files. Directives, bundler annotations, and `Why:` notes are kept; JSX comments and comments next to `disable-next-line` are reported without an autofix. |
|
|
152
|
+
| `no-member-comments` 🔧 | No comments on interface, type, and object members. [Details ↓](#no-member-comments) |
|
|
153
|
+
| `test-title-pattern` | Test titles match your rules, for example no leading "should". |
|
|
154
|
+
|
|
155
|
+
### 🎨 Layout
|
|
156
|
+
|
|
157
|
+
| Rule | What it enforces |
|
|
158
|
+
| --- | --- |
|
|
159
|
+
| `padding-between-statements` 🔧 | Blank lines around functions and classes, around control flow, and before `return` in longer blocks. |
|
|
160
|
+
| `object-multiline` 🔧 | Objects with 3+ properties passed to a call go one property per line (`scope: 'all'` for every object). |
|
|
161
|
+
| `key-value-same-line` 🔧 | An object key and the start of its value stay on the same line. |
|
|
162
|
+
| `chain-newline` 🔧 | Long method chains go one call per line. You pick which chains with `groups`. |
|
|
163
|
+
| `call-array-multiline` 🔧 | Arrays passed to `Promise.all` (or callees you list) go one element per line. |
|
|
164
|
+
| `jsx-attributes-multiline` 🔧 | JSX tags with 3+ attributes go one attribute per line. |
|
|
165
|
+
|
|
166
|
+
> [!WARNING]
|
|
167
|
+
> Oxfmt and Prettier collapse short chains, arrays, and JSX tags back onto one line. Don't run `chain-newline`, `call-array-multiline`, or `jsx-attributes-multiline` on files a formatter also rewrites, or they will undo each other forever.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 🔍 Rule details
|
|
172
|
+
|
|
173
|
+
### `no-inline-types`
|
|
174
|
+
|
|
175
|
+
Requires named types in function signatures: local functions, callbacks, methods, constructors, and overloads. It checks explicit annotations only; inferred types, variable annotations, and generic constraints are left alone.
|
|
176
|
+
|
|
177
|
+
| Option | Default | What it does |
|
|
178
|
+
| --- | --- | --- |
|
|
179
|
+
| `parameters` | `true` | Check parameter annotations, including destructuring, defaults, rest, and constructor parameter properties. |
|
|
180
|
+
| `returns` | `true` | Check explicit return annotations. |
|
|
181
|
+
| `functionTypes` | `true` | Also reject inline function and constructor types. |
|
|
182
|
+
| `minMembers` | `1` | Allow inline object types with fewer members than this. `1` also rejects `{}`. |
|
|
183
|
+
|
|
184
|
+
Nested types count too, so `Promise<{ id: string }>` fails. An outer type is reported once, not again for each member inside it.
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
// ✅ Pass
|
|
188
|
+
function save(input: SaveInput): SaveResult { return persist(input) }
|
|
189
|
+
|
|
190
|
+
// ❌ Fail
|
|
191
|
+
function save(input: { id: string }): { ok: boolean } { return persist(input) }
|
|
37
192
|
```
|
|
38
193
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
## Configuration examples
|
|
42
|
-
|
|
43
|
-
- [`examples/minimal.oxlint.config.ts`](examples/minimal.oxlint.config.ts) — three small rules showing plugin registration, glob ownership, and options.
|
|
44
|
-
- [`examples/full.oxlint.config.ts`](examples/full.oxlint.config.ts) — all 27 rules across representative component, action, service, route, API, schema, and database scopes.
|
|
45
|
-
|
|
46
|
-
Copy the shapes that match your repository; do not copy globs or naming policy blindly.
|
|
47
|
-
|
|
48
|
-
## Rules
|
|
49
|
-
|
|
50
|
-
- `declaration-name` — require selected declarations to match a filename-derived prefix or a consumer pattern. Optional `trailingRoles` treat `onchain-utils.ts` like `onchain.utils.ts`.
|
|
51
|
-
- `export-file-prefix` — require export names, or every function and type, to start with a filename-derived prefix, optionally singularized. Optional `trailingRoles` drop a configured role suffix from that prefix.
|
|
52
|
-
- `export-name-pattern` — require export names, or every function and type, to match a configured regular expression.
|
|
53
|
-
- `filename-export-name` — derive expected function names from filename templates, optionally including locals.
|
|
54
|
-
- `filename-match` — require filenames to match a configured pattern.
|
|
55
|
-
- `folder-prefix` — require filenames to start with their parent folder name, or the folders after a configured root.
|
|
56
|
-
- `no-extra-exports` — restrict files to configured export templates. Optional `trailingRoles` apply to `{Domain}` the same way as the prefix rules.
|
|
57
|
-
- `no-extra-factory-keys` — restrict direct factory return keys.
|
|
58
|
-
- `no-file-level-helpers` — keep unapproved helpers out of module scope.
|
|
59
|
-
- `no-imported-type-alias` — reject exported aliases that only rename imported types.
|
|
60
|
-
- `no-inline-schema-elements` — require named schemas inside configured combinators.
|
|
61
|
-
- `no-local-schema-construction` — reject runtime schema-library imports and local schema construction, with consumer-chosen severity, messages, and path exceptions.
|
|
62
|
-
- `no-rederive-schema` — reject type derivation from configured imported schemas.
|
|
63
|
-
- `no-restricted-files` — reject files selected by a consumer-owned forbidden glob.
|
|
64
|
-
- `no-restricted-token` — restrict an identifier to configured owner paths.
|
|
65
|
-
- `no-runtime-in-types` — keep selected type modules runtime-free.
|
|
66
|
-
- `no-single-use-scalar-schema` — reject local scalar Zod aliases used once where they can be safely inlined.
|
|
67
|
-
- `no-top-level-functions` — reject top-level functions and optional re-exports.
|
|
68
|
-
- `no-trivial-functions` — reject empty or passthrough top-level functions.
|
|
69
|
-
- `no-type-declarations` — reject type aliases and interfaces in matched files.
|
|
70
|
-
- `no-unescaped-like` — require configured sanitizers for configured query methods.
|
|
71
|
-
- `only-export-components` — allow only React component and type exports.
|
|
72
|
-
- `require-file-factory` — derive and require a filename-based factory function.
|
|
73
|
-
- `require-object-params` — require exported functions to use object-shaped parameters.
|
|
74
|
-
- `require-orpc-output` — require named oRPC output schemas.
|
|
75
|
-
- `require-paired-call` — require one configured call when another appears.
|
|
76
|
-
- `route-surface` — constrain route exports, hooks, and intrinsic JSX.
|
|
77
|
-
|
|
78
|
-
Every rule file includes plain-English behavior and examples. Rule tests under `src/tests/` show complete option shapes.
|
|
79
|
-
|
|
80
|
-
## Development
|
|
194
|
+
<details>
|
|
195
|
+
<summary>More about <code>no-inline-types</code></summary>
|
|
81
196
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
197
|
+
Use `no-type-declarations` separately to control where named types may live. With `functionTypes: false`, object types nested inside function types are still checked.
|
|
198
|
+
|
|
199
|
+
</details>
|
|
200
|
+
|
|
201
|
+
### `only-export-constants`
|
|
202
|
+
|
|
203
|
+
Every runtime export must point to a local `const`. Direct, destructured, renamed, and default exports of local constants all work.
|
|
204
|
+
|
|
205
|
+
| Option | Default | What it does |
|
|
206
|
+
| --- | --- | --- |
|
|
207
|
+
| `allowFunctionValues` | `false` | Allow function-valued `const` bindings (not function declarations). |
|
|
208
|
+
| `allowTypeExports` | `false` | Allow type aliases, interfaces, and type-only exports. |
|
|
209
|
+
| `allowReExports` | `false` | Allow `export ... from`, `export *`, and exports of imported bindings. |
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
// ✅ Pass
|
|
213
|
+
const retryLimit = 3
|
|
214
|
+
export { retryLimit }
|
|
215
|
+
|
|
216
|
+
// ❌ Fail
|
|
217
|
+
export let retryCount = 0
|
|
218
|
+
export const retry = () => run()
|
|
85
219
|
```
|
|
86
220
|
|
|
87
|
-
|
|
221
|
+
<details>
|
|
222
|
+
<summary>More about <code>only-export-constants</code></summary>
|
|
88
223
|
|
|
89
|
-
|
|
224
|
+
`let`, `var`, function, class, enum, and namespace declarations, class-valued constants, bare default expressions, and TypeScript `export =` / `export as namespace` are rejected. Name a default value with a local `const` first.
|
|
90
225
|
|
|
91
|
-
|
|
226
|
+
This is a syntax rule, not a deep-immutability check. It recognizes direct function and class values, TypeScript expression wrappers, and local aliases. It does not follow values returned by calls, imports, member access, or destructuring. Objects and arrays do not need `as const` or `Object.freeze()`.
|
|
92
227
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
228
|
+
</details>
|
|
229
|
+
|
|
230
|
+
### `no-restricted-token`
|
|
231
|
+
|
|
232
|
+
Keeps identifiers and member calls inside the files that own them.
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
'arch/no-restricted-token': ['error', {
|
|
236
|
+
restrictions: [
|
|
237
|
+
{ token: 'RouterClient', allowIn: ['/src/services/rpc.client.ts'] },
|
|
238
|
+
{ member: 'process.platform', allowIn: ['/src/runtime.ts'] },
|
|
239
|
+
{ member: '*.insertInto', message: 'Queries are read-only; move writes to an action.' },
|
|
240
|
+
],
|
|
241
|
+
}]
|
|
97
242
|
```
|
|
98
243
|
|
|
99
|
-
|
|
244
|
+
| Field | What it does |
|
|
245
|
+
| --- | --- |
|
|
246
|
+
| `token` | An identifier name to restrict. Type-only imports are ignored. |
|
|
247
|
+
| `member` | A dotted member path such as `process.platform`. `*.name` matches any receiver, including `this.db` and chained calls. |
|
|
248
|
+
| `allowIn` | Filename suffixes where the token is allowed. |
|
|
249
|
+
| `allowPathPatterns` | Regular expressions for allowed paths. |
|
|
250
|
+
| `message` | Extra guidance added to the report. |
|
|
251
|
+
|
|
252
|
+
The older single form `{ token, allowIn }` still works.
|
|
253
|
+
|
|
254
|
+
### `no-member-comments`
|
|
255
|
+
|
|
256
|
+
Removes comments on object-type members: interface properties and methods, index, call, and construct signatures, type-literal members, object literal properties, and spreads.
|
|
257
|
+
|
|
258
|
+
| Kept ✅ | Removed ❌ |
|
|
259
|
+
| --- | --- |
|
|
260
|
+
| `Why: ...` notes (with `allowWhy: true`, the default) | Other leading and same-line trailing member comments |
|
|
261
|
+
| Directives such as `@ts-expect-error`, `eslint-disable`, `prettier-ignore` | |
|
|
262
|
+
|
|
263
|
+
<details>
|
|
264
|
+
<summary>Autofix and scope details</summary>
|
|
265
|
+
|
|
266
|
+
The autofix removes the comment and any blank line after it, drops the spaces before a trailing comment, and never removes the member itself. A run of stacked comments is removed by one fix, so `--fix` finishes in one pass.
|
|
267
|
+
|
|
268
|
+
`Why:` detection checks the prefix (after whitespace or JSDoc decoration) and includes contiguous `//` continuation lines. Set `{ allowWhy: false }` to remove those too. Always-kept directives: `@ts-ignore`, `@ts-expect-error`, `@ts-nocheck`, `eslint-`/`oxlint-disable`/`enable`, `prettier-ignore`, `biome-ignore`, `c8`/`v8`/`istanbul ignore`, and webpack magic comments.
|
|
269
|
+
|
|
270
|
+
Out of scope: declaration, function-body, class-field, enum-member, union-member, and plain parameter comments, plus comments inside destructuring patterns and array literals. For whole-file comment policy, use `no-comments`.
|
|
271
|
+
|
|
272
|
+
</details>
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## 🤝 Works well with anti-slop
|
|
277
|
+
|
|
278
|
+
We recommend [Dillon Mulroy's anti-slop](https://github.com/dmmulroy/anti-slop) alongside this plugin:
|
|
279
|
+
|
|
280
|
+
| Plugin | Catches |
|
|
281
|
+
| --- | --- |
|
|
282
|
+
| **anti-slop** | Low-evidence TypeScript and JavaScript patterns inside functions. |
|
|
283
|
+
| **oxlint-plugin-arch** | File, export, boundary, API, and layout structure. |
|
|
284
|
+
|
|
285
|
+
Register both in the same config; they use separate `anti-slop/*` and `arch/*` namespaces.
|
|
286
|
+
|
|
287
|
+
## ⚡ Benchmarks
|
|
288
|
+
|
|
289
|
+
Wall time for a full `oxlint` run over three real TypeScript monorepos, best of 5, including process startup.
|
|
290
|
+
|
|
291
|
+
| Project | Files | Lines | Plugin loaded, no rules | [Monorepo example](examples/monorepo.oxlint.config.ts) | All 42 rules on every file |
|
|
292
|
+
| --- | ---: | ---: | ---: | ---: | ---: |
|
|
293
|
+
| Small | 246 | 14.5k | 0.09s | **0.20s** | 0.23s |
|
|
294
|
+
| Medium | 792 | 100.5k | 0.10s | **0.49s** | 0.69s |
|
|
295
|
+
| Large | 1,880 | 190k | 0.10s | **0.72s** | 1.08s |
|
|
296
|
+
|
|
297
|
+
<sub>Apple M5 Pro, Oxlint 1.78.0, default thread count. Most of the gap between "no rules" and the other columns is Oxlint's one-time cost of handing the AST to JavaScript plugins, paid once however many rules are on.</sub>
|
|
100
298
|
|
|
101
|
-
## License
|
|
299
|
+
## 📄 License
|
|
102
300
|
|
|
103
301
|
MIT
|