Repository navigation
Lint the repository with Oxlint and dogfood the machine rules - #260
Merged
Merged
Conversation
5 of 6 tasks
Contributor
Type performanceMeasured with TypeScript 6.0.3 and
Marginal instantiations are measured against the matching setup without that API call:
Check times (informational)
Type instantiations are the comparison metric. Check time varies with runner load and is informational only. |
Contributor
Runtime performanceMedian of 5 independent benchmark processes on Pull request baseline
Process runtime reference points
Effect Machine change from base
Process runtime reference change from base
Regression guardNo large, noise-adjusted throughput or heap regressions detected. Versions and interpretation
Higher throughput is better; lower heap is better. Variability is the median absolute deviation across independent processes, relative to their median. Small differences on shared GitHub-hosted hardware remain informational; the required guard rejects only large changes beyond the measured noise allowance. |
Add `pnpm lint` to `pnpm check`. It builds the local @typeonce/oxlint-plugin-effect-machine package and runs Oxlint 1.90.0 with type-aware rules through oxlint-tsgolint. The plugin's rules check the devtools example machines and the machine test fixtures. The root tsconfig references the test project so type-aware rules and editors use the repository's compiler options for tests. Fix the findings: remove unnecessary type assertions, empty parameter patterns, redundant renames and spreads, useless regex escapes, and add the missing switch cases. The few assertions that TypeScript 6 still requires keep a justified suppression. Formatting stays on dprint, which Effect also uses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SandroMaglione
force-pushed
the
repository-oxlint
branch
from
November 1, 2026 09:47
203d4b3 to
8fa0d9f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add Oxlint to the repository and run the repository's own Effect Machine plugin on its machines.
Formatter check.
Effect-TS/effectmain (pushed 2026-10-31) formats with dprint (^0.63.0) and lints with oxlint (^1.88.0):"lint": "oxlint -f unix && dprint check", withdprint.jsonand.oxlintrc.jsonat the root and no.oxfmtrc*, biome, or prettier config.Effect-TS/effect-smoland the local beta.98 mirror do the same with dprint 0.55 and oxlint 1.42. So formatting stays on dprint. This PR does not touch the dprint version; the dependency PR bumps it.Lint setup
.oxlintrc.json, modeled on the ritmo config: thecorrectnesscategory plus type-aware rules throughoxlint-tsgolint(no-unnecessary-type-assertion,switch-exhaustiveness-check,no-floating-promises,no-misused-promises) andno-unused-varswith_ignore patterns. Pinsoxlint1.90.0 to match the dependency-bump PR, andoxlint-tsgolint7.0.2005.pnpm lintbuilds@typeonce/oxlint-plugin-effect-machine(workspace:*, loaded as a jsPlugin) and then runsoxlint, so it works in a fresh clone. It runs inpnpm checkright afterformat:check, so the CIcheckandlatest-effectjobs both run it. I did not add a separateci.ymlstep because it would run the same lint twice.packages/devtools/src/internal/browser/{example-machine,*-example}.ts) and topackages/effect-machine/test/{fixtures,examples}. Docs snippets live in Markdown, which Oxlint cannot lint.tsconfig.jsonnow referencestsconfig.tests.json. Without it, tsgolint (and editors) type-checked tests in an inferred project withoutnoUncheckedIndexedAccess, which produced about 180 false "unnecessary!" reports.tsc -band every script that reads a tsconfig are unaffected.Rules left out or turned off, and why
scripts/**belong to no tsconfig, so type-aware rules are off there. Type tests and perf fixtures also skipno-unused-vars: type tests bind values only to check their types, and the perf fixtures stay byte-stable so type-performance comparisons stay valid.no-unused-varsis off forpackages/*/src/**. Public and internal types keep phantom type parameters for variance and inference, andnoUnusedLocalsalready checks the rest.no-unnecessary-type-arguments(in ritmo's set) is left out: Effect-style code spells outEffect.Effect<A, E, never>on purpose.no-redundant-type-constituentsis off: unions such asunknown | StoppedErrorandstring | "dynamic"document the intended values.unicorn/no-new-arrayis off, as in Effect's config: the execution plan preallocates arrays.no-this-aliasallowsself, the capture idiom forEffect.genbodies.Fixes (no behavior change)
oxlint-disable-next-line. TypeScript 6.0.3 needs them, but the TypeScript 7 checker in tsgolint does not:TargetSelectionTypeIdkey,finiteModel.ts,The
as neverinPaths.test.tsalso stays: TypeScript 6 rejects the reservedrootstate name there, but TypeScript 7 accepts it. That may be a type-level gap under TS 7 worth checking in the TS 7 lane.({}) =>to() =>, and{ input: input }to{ input }....{ literal }and array spreads that did nothing....(values ?? {})to...values.String(src)in an invocation error message (a symbol in a template literal would throw).defaultin the schema-arbitrary visitor, and a missingactivecase in a test switch.await act(async () => …)in the React tests.= undefined.invoke-outcomes-example.tsselects a titlednonebranch from anonSnapshotresolver.Machine.candoes not query snapshot outcomes, so this is a false positive. Check no-conditional-none-branch only on event handlers #257 fixes it by limitingno-conditional-none-branchtoonhandlers. The suppression can go once Check no-conditional-none-branch only on event handlers #257 merges.Coordination
executionPlan.ts, which another in-flight change is also reducing. Whichever merges second should resolve the conflict and rerunpnpm lint.no-duplicate-sibling-transitions,no-guarded-none, andno-runsync-machine-canto the dogfood override and drop the snapshot suppression. I ran all 14 rules from Check no-conditional-none-branch only on event handlers #257 on these 13 files: 0 findings.package.jsonandpnpm-lock.yamlwill need a trivial rebase against the dependency and TS 7 PRs.Changeset
Validation
pnpm check: format, lint, architecture, CI scripts, API docs, site docs, typecheck, build, 901 tests, type tests (246 tests and 1,299 assertions in core, 35 assertions in React), consumer, and all four pack checks passed.git clone+pnpm install --frozen-lockfile+pnpm lint): builds the plugin, then lints 318 files with 119 rules, exit 0.pnpm linttakes about 8–9 s end to end (oxlint alone 5.5–15 s, depending on machine load).latest-effectsimulation (scripts/prepare-effect-compatibility.mjs, Effect 4.1.1):oxlintandpnpm typecheckboth pass.🤖 Generated with Claude Code