Repository navigation
chore: migrate tooling to oxlint, oxfmt and tsc - #2422
Conversation
Lint and type check - `check`/`fix` run oxlint with type-aware rules and type checking (via oxlint-tsgolint), covering packages, tests, *.test-d.ts and playgrounds; `format` runs oxfmt and is not checked in CI - port the ban/restricted-globals/restricted-imports rules to `no-restricted-properties`, `no-restricted-globals` and `no-restricted-imports` - `correctness` and `suspicious` categories as errors; rules that would change public types or misfire on oRPC patterns are turned off with a reason - fix the remaining findings: `void` for intentionally floating promises, `toSorted` outside packages, stale disable directives - remove eslint, @antfu/eslint-config, eslint plugins, lint-staged, simple-git-hooks and sherif TypeScript - TypeScript 7 for builds and type checks; the docs JSDoc checker keeps the TypeScript 6 API through the `typescript-6` alias - inline tsconfig.base.json into tsconfig.json + tsconfig.lib.json - `module: nodenext`, `verbatimModuleSyntax`; relative imports use explicit `.ts` extensions, rewritten to `.js` on build - drop project references and per-package include/exclude; bun, cloudflare and nest type check with tsconfig.json and build with tsconfig.build.json - rename next's server-function.test.tsx, which shadowed server-function.test.ts and was never type checked Build - replace obuild with plain `tsc` (per-file .js + .d.ts in dist) and drop verifyDist Editors and agents - VS Code recommends the oxc extension; VS Code and Zed format and fix on save through oxfmt and oxlint - the Claude Code hook formats edited files with oxfmt - CLAUDE.md becomes AGENTS.md (CLAUDE.md imports it) Misc - pin pnpm via `packageManager` instead of `devEngines` Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVaw7NPXNhdw5kppy7fFNE
Run `pnpm format` across the repo, and move the `@ts-expect-error` directives that the reformat separated from the line they expect an error on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVaw7NPXNhdw5kppy7fFNE
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVaw7NPXNhdw5kppy7fFNE
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVaw7NPXNhdw5kppy7fFNE
- oxlint: start from standard-server's config; keep oRPC's restriction rules, turn off only rules whose fixes would change public types or break type checking, plus test-fixture patterns; fix the rest (`void` for intentional floating promises, `import * as z from 'zod'`, explicit `return undefined`, `toSorted`/`toReversed` in tests, ...) - `oxlint-disable` comments instead of `eslint-disable`, inline in scripts - drop ignorePatterns: generated sponsor modules are formatted by `sponsors:sync`, and vendored agent skills are no longer committed (restore them with `npx skills experimental_install`) - tsconfig: drop allowImportingTsExtensions, resolveJsonModule, isolatedDeclarations and the package.json include - vitest only excludes .claude/worktrees; dependabot without groups; VS Code settings as in standard-server - remove CLAUDE.md and the Claude Code format hook; run `pnpm format` manually - AGENTS.md: multi-scope PR title example Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVaw7NPXNhdw5kppy7fFNE
- oxlint: keep `no-base-to-string`, `no-unnecessary-type-parameters`, `no-redundant-type-constituents`, `no-unassigned-import`, `consistent-function-scoping`, `no-array-sort`/`no-array-reverse`, `no-thenable`, `no-extraneous-class` and `no-misused-spread` on as in standard-server, with inline disables at the few intentional sites; move `no-unassigned-import` and `consistent-function-scoping` to the test override; hoist `isPrimitive` and `countWords` - `oxlint-disable-next-line` instead of the trailing `disable-line` - packages/node uses lib ES2022 like standard-server's node packages - pnpm 12.16.1; cloudflare playground on TypeScript 7 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVaw7NPXNhdw5kppy7fFNE
The tests import from vitest, so vitest/globals is not needed; matches tsconfig.build.json. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVaw7NPXNhdw5kppy7fFNE
Move the rule into the root rules and add apps/content to the override that relaxes rules for tests and playgrounds; drop the disables and lint-only edits there that this makes unnecessary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVaw7NPXNhdw5kppy7fFNE
skills-lock.json does not pin a version (restoring downloads the latest upstream and rewrites the hash), so commit the reviewed skills and leave them to lint and format through ignorePatterns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVaw7NPXNhdw5kppy7fFNE
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
orpc | a2218b0 | Commit Preview URL Branch Preview URL |
Nov 05 2026, 10:01 AM |
More templates
@orpc/ai-sdk
@orpc/arktype
@orpc/bun
@orpc/client
@orpc/cloudflare
@orpc/contract
@orpc/effect
@orpc/evlog
@orpc/hibernation
@orpc/json-schema
@orpc/experimental-lock
@orpc/mcp
@orpc/msw
@orpc/nest
@orpc/next
@orpc/node
@orpc/openapi
@orpc/opentelemetry
@orpc/pinia-colada
@orpc/pino
@orpc/publisher
@orpc/ratelimit
@orpc/server
@orpc/shared
@orpc/swr
@orpc/tanstack-query
@orpc/trpc
@orpc/valibot
@orpc/zod
commit: |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Merging this PR will not alter performance1 warning
Comparing Footnotes
|
- `pnpm repo:fix` runs `sherif --fix`, ignoring the TypeScript 6 the next and nest playgrounds need for the compiler API - dependabot groups `@standard-server/*`, `@openapi-spec/*` and dev dependency minor/patch updates Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVaw7NPXNhdw5kppy7fFNE
sherif only matches exact versions, so `typescript@^6.0.3` would stop matching once the TypeScript 6 playgrounds are bumped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVaw7NPXNhdw5kppy7fFNE
`compression` was inlined into @orpc/interop, which #1653 removed together with the dependency, so the dependabot exclude and the restricted import no longer match anything. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVaw7NPXNhdw5kppy7fFNE
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
- Lint and type check move to oxlint:
check/fixnow run oxlint withtypeAwareandtypeCheck, foldingpnpm type:checkinto one command; ESLint, its plugins, lint-staged, simple-git-hooks and sherif are removed. - Build moves from obuild to
tsc: per-file.js/.d.tsemit,prepack: tscin every package, publish exports switched from.mjs/.d.mtsto.js/.d.ts, and everybuild.config.tsplusverifyDistdeleted. - Module resolution and tsconfigs:
module: nodenext,verbatimModuleSyntax, explicit.tsrelative imports rewritten on emit;tsconfig.base.jsonfolded intotsconfig.json+tsconfig.lib.json; project references dropped; bun, cloudflare and nest pinned to their own build configs. - Lint-fix code edits:
voidon intentionally floating promises,toSortedin tests and scripts, explicitreturn undefined,{ cause }on the retryTypeError,String()inside template literals, and a rename ofpackages/next/src/server-function.test.tsxso it is actually type checked. - Reformat: oxfmt across source, docs
.mdxcode samples, JSON/JSONC and markdown, with the moved@ts-expect-errordirectives re-anchored. - Repo/agent config:
CLAUDE.mdand the Claude format hook replaced byAGENTS.md, VS Code/Zed switched to oxc, dependabot groups dropped, pnpm pinned viapackageManager, and the vendored.agents/skillscommitted and excluded viaignorePatterns.
I verified the central claims against the branch with a fresh install: pnpm check passes and genuinely type checks (injected TS2322/TS18048, *.test-d.ts assertion failures, and a process.cwd() probe in @orpc/shared were all reported, and strict mode is on), oxfmt --check passes, oxlint --fix leaves the tree clean, all 29 packages build with prepack, and a consumer importing the built dist of @orpc/server, @orpc/client, @orpc/shared and @orpc/openapi type-checks and runs under Node. I also confirmed every publishConfig export target maps to an existing src file, dev and publish export keys match in all packages, and the emitted dist has no relative-import breakage, undeclared dependencies or import cycles. Root vitest gives 4387 passing; the only failures were three tests in tests/rpc/cancel-and-abort.test.ts, which pass when that file is run alone (pre-existing timing flake under load — the file's diff is import-extension only). pnpm docs:validate and blume build both succeed.
ℹ️ verifyDist guardrails no longer run
The obuild hook that failed publishing on undeclared imports, relative imports to non-emitted files, and import cycles is gone. I re-ran all three checks against the current emitted dist by hand and found no violations — only bun and cloudflare:workers platform imports exist outside declared dependencies, no cycles, and every relative specifier resolves. Worth knowing that nothing will catch these automatically on future changes, especially now that declarations are emitted per file rather than through a bundler hook.
deepseek-v4.1-flash-1017 (free via Pullfrog for OSS) | 𝕏
|
Re the Pullfrog note that Generated by Claude Code |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes (incremental since the prior review at d5c78e8)
- sherif restored:
repo:fixscript (sherif --fix -i typescript),sherif ^1.13.0in devDependencies, and theAGENTS.mdcommand list updated.-i typescriptcorrectly suppresses the only finding sherif reports (multiple-dependency-versionsfortypescript, because the next and nest playgrounds deliberately stay on TS6);sherif -i typescriptexits clean. - Dependabot groups restored:
@standard-server/*,@openapi-spec/*and dev-dependency minor/patch. Theeslintgroup stays gone with the ESLint removal. - Compression cleanup:
compressiondropped fromno-restricted-importsand from the dependabot exclude patterns. That was genuinely leftover — it only ever appeared as a package keyword, never as a dependency or source import. - PR description and
AGENTS.mdupdated to match the restoredrepo:fixcommand.
Re-verified after these commits: pnpm install --frozen-lockfile is consistent with the lockfile, pnpm check still reports 0 warnings/errors, oxfmt --check still passes, and the working tree stays clean.
deepseek-v4.1-flash-1017 (free via Pullfrog for OSS) | 𝕏
Since #2422, `tsc` built the packages and dropped imports from declarations when their only use was inside a `declare module` augmentation that another file of the program also augmented: `@orpc/effect/extensions/effect` lost `DecoratedProcedure`, so `.effect()` returned an unresolved type and `createRouterClient` accepted any context and input. tsc's import elision depends on the whole program, so this can come back with any new augmentation. obuild's transform mode emits one `.mjs` + `.d.mts` per file with oxc's isolated declarations, which only depend on the file itself: - one shared `build.config.ts` at the root, run by every package's `prepack` (`node ../../build.config.ts`) - `import x from './file.json' with { type: 'json' }` is inlined into the emitted code, keeping only the properties that are read (`@orpc/opentelemetry` reads `name` and `version` of package.json) - `verifyDist` from before #2422 is back: dependencies, emitted relative imports, import cycles, missing declarations (obuild only warns on `isolatedDeclarations` errors) and package.json paths - `pnpm build` builds and verifies every package, and CI runs it - `isolatedDeclarations` in tsconfig.lib.json, with explicit types in `@orpc/shared` regexes - exports move back from `.js`/`.d.ts` to `.mjs`/`.d.mts` - the `DecoratedProcedure` alias workaround in the effect extension is reverted Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VVaw7NoNaJhK4MBSMMhE4E

Follows middleapi/standard-server#184: replace ESLint and obuild with oxlint, oxfmt and plain
tsc, matching standard-server's configs except where oRPC needs something different (listed below).Lint and type check
pnpm check/pnpm fixrun oxlint with type-aware rules and type checking (via oxlint-tsgolint). This covers packages, tests,*.test-d.ts, playgrounds and the docs site, and replaces bothpnpm lintandpnpm type:check.pnpm formatruns oxfmt. CI doesn't check formatting.JSON.stringify,.bytes,throwIfAbortedandAbortSignal.anyas banned properties, plus restricted globals and restricted imports.voidon intentional fire-and-forget promisesimport * as z from 'zod'return undefinedtoSorted/toReversedoutside packagesoxlint-disable-next-lineat the few deliberate sitesTypeScript and build
module: nodenextandverbatimModuleSyntax. Relative imports use explicit.tsextensions, whichtscrewrites to.js.tsconfig.base.jsonis folded intotsconfig.json+tsconfig.lib.json, and project references are dropped.tsc(per-file.js+.d.ts). Exports change from.mjs/.d.mtsto.js/.d.ts. obuild,build.config.tsandverifyDistare removed.tsconfig.json(which includes their tests) and build withtsconfig.build.json.packages/next/src/server-function.test.tsxshared its name withserver-function.test.ts, so TypeScript skipped it and it was never type checked. It's renamed toserver-function.action-state.test.tsx.Formatting
The repo is reformatted with oxfmt, including code samples in docs
.mdxfiles, in its own commit (chore: format with oxfmt) to keep review manageable.@ts-expect-errordirectives that the reformat moved away from their error lines are moved back.Repo
pnpm check.@standard-server/*,@openapi-spec/*and dev-dependency minor/patch updates.pnpm repo:fixrunssherif --fix, ignoringtypescriptversions because the next and nest playgrounds stay on TypeScript 6 on purpose. sherif only matches exact versions, so a version-specific ignore would stop working after the next bump.packageManager: pnpm@12.16.1.CLAUDE.mdand the Claude Code format hook are removed;AGENTS.mdis the concise instructions file.ignorePatterns.skills-lock.jsondoesn't pin versions, so git is the pin.Differences from standard-server
no-generated-empty-object-type: fixing it would change public types.no-unnecessary-type-assertion: its auto-fix broke type checking on generic code.unbound-method: about 400 false positives onnexttaken from interceptor options.no-shadow: 127 hits in package source.apps/content, and turns offrequire-yield,no-unsafe-optional-chainingandawait-thenablefor test fixtures.jsxand the.test.tsx/__tests__entries in the tsconfigs.typescript-6alias for the docs JSDoc checker, which needs the TS compiler API that TS7 doesn't have.docs:validatestep in CI.Verification
pnpm checkandoxfmt --checkpass.@orpc/cloudflare81 (workerd),@orpc/bun100.tsc.pnpm docs:validatepasses, andblume buildsucceeds.For contributors: existing clones still have simple-git-hooks' pre-commit hook, which calls the removed
lint-staged. Delete it once withrm .git/hooks/pre-commit.🤖 Generated with Claude Code
https://claude.ai/code/session_01VVaw7NPXNhdw5kppy7fFNE