Skip to content

feat(trpc): tRPC integration - #1683

Merged
dinwwwh merged 13 commits into
middleapi:mainfrom
dinwwwh:claude/orpc-v2-trpc-integration-3b6f96
Jul 19, 2026
Merged

feat(trpc): tRPC integration#1683
dinwwwh merged 13 commits into
middleapi:mainfrom
dinwwwh:claude/orpc-v2-trpc-integration-3b6f96

Conversation

@dinwwwh

@dinwwwh dinwwwh commented Jul 18, 2026

Copy link
Copy Markdown
Member

Summary

Brings the tRPC integration (@orpc/trpc) to v2. You can now convert a tRPC router into an oRPC router and use it with any oRPC feature:

const orpcRouter = toORPCRouter(trpcRouter)
  • Works with RPC/OpenAPI handlers, server-side clients, OpenAPI spec generation, subscriptions (including tracked events), and lazy routers
  • toTRPCMeta lets you use oRPC meta plugins (like openapi(...)) directly in tRPC's .meta()
  • New tRPC Integration docs page
  • 100% test coverage

Port the @orpc/trpc package from v1 to v2, allowing tRPC routers to be
converted into oRPC routers via toORPCRouter, including OpenAPI support,
subscriptions/tracked events, lazy routers, and error conversion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
orpc Ready Ready Preview, Comment Jul 19, 2026 3:22am

@pkg-pr-new

pkg-pr-new Bot commented Jul 18, 2026

Copy link
Copy Markdown
More templates

@orpc/arktype

npm i https://pkg.pr.new/@orpc/arktype@1683

@orpc/bun

npm i https://pkg.pr.new/@orpc/bun@1683

@orpc/client

npm i https://pkg.pr.new/@orpc/client@1683

@orpc/cloudflare

npm i https://pkg.pr.new/@orpc/cloudflare@1683

@orpc/contract

npm i https://pkg.pr.new/@orpc/contract@1683

@orpc/experimental-effect

npm i https://pkg.pr.new/@orpc/experimental-effect@1683

@orpc/evlog

npm i https://pkg.pr.new/@orpc/evlog@1683

@orpc/json-schema

npm i https://pkg.pr.new/@orpc/json-schema@1683

@orpc/nest

npm i https://pkg.pr.new/@orpc/nest@1683

@orpc/next

npm i https://pkg.pr.new/@orpc/next@1683

@orpc/openapi

npm i https://pkg.pr.new/@orpc/openapi@1683

@orpc/opentelemetry

npm i https://pkg.pr.new/@orpc/opentelemetry@1683

@orpc/pino

npm i https://pkg.pr.new/@orpc/pino@1683

@orpc/publisher

npm i https://pkg.pr.new/@orpc/publisher@1683

@orpc/ratelimit

npm i https://pkg.pr.new/@orpc/ratelimit@1683

@orpc/server

npm i https://pkg.pr.new/@orpc/server@1683

@orpc/shared

npm i https://pkg.pr.new/@orpc/shared@1683

@orpc/tanstack-query

npm i https://pkg.pr.new/@orpc/tanstack-query@1683

@orpc/trpc

npm i https://pkg.pr.new/@orpc/trpc@1683

@orpc/valibot

npm i https://pkg.pr.new/@orpc/valibot@1683

@orpc/zod

npm i https://pkg.pr.new/@orpc/zod@1683

commit: fe44c11

@codecov

codecov Bot commented Jul 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codspeed-hq

codspeed-hq Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 18 untouched benchmarks


Comparing dinwwwh:claude/orpc-v2-trpc-integration-3b6f96 (fe44c11) with main (61ef170)

Open in CodSpeed

@pullfrog

pullfrog Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Minor suggestions only. Package type-checks and all 11 new tests pass.

Reviewed changes — port of the @orpc/trpc package from v1 to v2, adding toORPCRouter to convert tRPC routers into oRPC routers, plus tests and docs.

  • Add @orpc/trpc package with toORPCRouter, ORPCMeta, and ToORPCRouterResult type mapping.
  • Adapt to v2 architecture by preserving tRPC schemas while disabling oRPC validation, forwarding meta (including ~openapi), wrapping TRPCError as ORPCError, and supporting lazy/subscription routers.
  • Add docs and fix migration link with a new docs/integrations/trpc.md page and corrected sidebar entry.

Feedback

  • packages/trpc/package.json:39⚠️ The package imports from @trpc/server/unstable-core-do-not-import for parser/iterator helpers, but the peer dependency has no upper bound. Because the unstable namespace is explicitly semver-exempt, a future tRPC v12 could break this integration. Consider "@trpc/server": ">=11.4.2 <12".

  • packages/trpc/src/to-orpc-router.ts:126 — ℹ️ isObject(input) is also true for arrays, so a subscription input that is an array would be converted to { '0': ..., lastEventId }. Consider guarding with !Array.isArray(input) if array inputs are supported.

  • packages/trpc/src/to-orpc-router.ts:137-138 — ℹ️ batchIndex: 0 is hard-coded with a TODO, so converted procedures won't behave correctly under the oRPC Batch Plugin. Worth tracking if batch plugin support is a goal.

  • apps/content/docs/integrations/trpc.md:118 — ℹ️ The error-formatting snippet uses z.ZodError, z.prettifyError, and z.flattenError but doesn't show a zod import. Adding it keeps the example copy-pasteable.

Pullfrog  | View workflow run | via Pullfrog | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

@pullfrog

pullfrog Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

test comment 2

Pullfrog  | View workflow run | via Pullfrog | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

Users now type the recommended '~openapi' meta key themselves using
OpenAPIMeta from @orpc/openapi, or expose any custom key via the new
mapMeta option. This drops @orpc/openapi from runtime dependencies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ Minor suggestions only. Package type-checks and all 11 new tests pass.

Reviewed changes — port of the @orpc/trpc package from v1 to v2, adding toORPCRouter to convert tRPC routers into oRPC routers, plus tests and docs.

  • Add @orpc/trpc package with toORPCRouter, ORPCMeta, and ToORPCRouterResult type mapping.
  • Adapt to v2 architecture by preserving tRPC schemas while disabling oRPC validation, forwarding meta (including ~openapi), wrapping TRPCError as ORPCError, and supporting lazy/subscription routers.
  • Add docs and fix migration link with a new docs/integrations/trpc.md page and corrected sidebar entry.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

Comment thread packages/trpc/package.json
Comment thread packages/trpc/src/to-orpc-router.ts
Comment thread packages/trpc/src/to-orpc-router.ts
Comment thread apps/content/docs/integrations/trpc.md
Cover dot-path lazy routers nested in plain object records, missing
parent segments in partially loaded routers, and non-TRPCError
passthrough from broken async iterables.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

The latest commits address some prior feedback (drop ORPCMeta, add mapMeta, reach 100% test coverage), but a few open concerns from the last review remain unresolved. I can't approve until they're addressed or explicitly accepted.

Reviewed changes — since the prior review, the package replaced the built-in ORPCMeta type with explicit '~openapi' typing and a user-supplied mapMeta option, and added tests covering dot-path lazy routers, partially loaded routers, scalar lastEventId input passthrough, and non-TRPCError rethrowing. Type-check and the 15 runtime tests pass.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

Comment thread packages/trpc/package.json
Comment thread packages/trpc/src/to-orpc-router.ts
Comment thread packages/trpc/src/to-orpc-router.ts
Comment thread apps/content/docs/integrations/trpc.md
Resolves oRPC meta plugins (e.g. openapi from @orpc/openapi) into a
plain meta object usable with tRPC builders' .meta(), simulating how
oRPC builders apply meta plugins.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

The new toTRPCMeta bridge is clean, but I cannot approve while three unresolved Pullfrog concerns remain on the tRPC package.

Reviewed changes — since the last review, the package added the toTRPCMeta helper so oRPC meta plugins can be used with tRPC builders, plus tests and docs.

  • Added toTRPCMeta in packages/trpc/src/to-trpc-meta.ts, wrapping resolveMetaPlugins from @orpc/contract to resolve oRPC meta plugins into a plain meta object.
  • Added @orpc/contract dependency and exported the new helper from packages/trpc/src/index.ts.
  • Added tests covering empty-plugin resolution, plugin merge logic, custom defineMeta plugins, and end-to-end conversion with toORPCRouter.
  • Updated docs/integrations/trpc.md to promote toTRPCMeta first and document the shallow-merge caveat of chained tRPC .meta() calls.
  • Resolved the previously open isObject(input)/lastEventId array-input concern by verifying that tRPC's isObject explicitly excludes arrays.

⚠️ @trpc/server peer dependency lacks an upper bound

packages/trpc/package.json declares "@trpc/server": ">=11.4.2". Because the code imports from @trpc/server/unstable-core-do-not-import, a future tRPC semver-major release could break the integration without a compatibility signal.

⚠️ Docs error-formatting snippet is missing imports

apps/content/docs/integrations/trpc.md uses z.ZodError, z.prettifyError, and z.flattenError in its error-formatting example, but the zod import is not shown, so the snippet is not copy-pasteable.

⚠️ batchIndex: 0 is hard-coded

packages/trpc/src/to-orpc-router.ts always passes batchIndex: 0 to tRPC procedures, with a TODO noting it should be inferred from context. Converted procedures will not behave correctly under the oRPC Batch Plugin.

Pullfrog  | Fix it ➔View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

No new issues in the latest commit, but this PR still cannot be approved until the unresolved Pullfrog review threads from the previous review are addressed.

Reviewed changes — the latest commit reorganized docs/integrations/trpc.md so the general router-conversion content comes before the OpenAPI section.

  • Moved router conversion to its own section explaining that the result is a regular oRPC router compatible with handlers, clients, middlewares, plugins, and interceptors.
  • Added call and createRouterClient examples showing direct procedure invocation and server-side clients.
  • Added an info box noting that input/output validation remains delegated to tRPC.

Pullfrog  | Fix it ➔View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

toTRPCMeta covers the meta-authoring use case; the docs now link to the
OpenAPI guides instead of duplicating them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

The latest commit is clean, but three unresolved concerns from prior reviews remain unaddressed.

Reviewed changes — since the prior review at f6298018, the package dropped the optional mapMeta API and the tRPC integration docs were trimmed.

  • Removed the mapMeta option from toORPCRouter: meta now passes straight through from tRPC, and users are expected to put OpenAPI metadata under '~openapi' (typically via toTRPCMeta).
  • Simplified the OpenAPI docs section by removing the manual OpenAPIMeta example and the request-handling code block; the page now links to the dedicated OpenAPI docs.
  • Removed the mapMeta test case and kept the rest of the test suite passing (18 tests).

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

Comment thread packages/trpc/package.json
Comment thread apps/content/docs/integrations/trpc.md
Comment thread packages/trpc/src/to-orpc-router.ts
Simplify lazy router conversion, wrap iterators via @orpc/shared
(dropping the @orpc/client dependency), mark returned errors opaque,
and verify the tRPC invocation contract with a mocked procedure.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Each test now creates only the router it needs; tests/shared.ts keeps
just the tRPC builder and schemas.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

The latest commit simplifies conversion internals, but it drops support for nested lazy routers and leaves a stale project reference.

Reviewed changes — since the prior review at 664a7954, the latest commit refactored lazy conversion and call forwarding.

  • Removed the @orpc/client dependency and switched from wrapAsyncIteratorPreservingEventMeta to @orpc/shared's wrapAsyncIterator while preserving event metadata explicitly.
  • Simplified lazy-router conversion by removing the accessible-proxy wrapper.
  • Added opaqueReturnedErrors: true to converted procedures.
  • Strengthened call tests to assert context, signal, path, type, and raw input forwarding.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

Comment thread packages/trpc/tsconfig.json Outdated
Comment thread packages/trpc/src/to-orpc-router.ts Outdated
dinwwwh and others added 2 commits July 19, 2026 09:38
Each test file now defines its own schemas and tRPC builder.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A plain throwing query cannot cover this path: tRPC wraps resolver
errors in TRPCError, so only errors thrown while consuming the returned
value escape unwrapped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

The latest commit is clean and the stale tsconfig.json reference is fixed, but several Pullfrog concerns from prior reviews remain unaddressed — most notably, nested lazy routers placed under plain object records are still inaccessible at runtime.

Reviewed changes — since the prior Pullfrog review at 77141d7, the PR cleaned up tests, removed the stale ../client project reference, loosened the toTRPCMeta return type, and restructured the tRPC integration docs. Type-check and the 15 runtime tests pass.

  • Restructured apps/content/docs/integrations/trpc.md to lead with router conversion and error formatting before covering toTRPCMeta in a dedicated Metadata section.
  • Removed the stale ../client project reference from packages/trpc/tsconfig.json after @orpc/client was removed as a dependency.
  • Loosened toTRPCMeta’s return type from Meta to Record<string, any> in packages/trpc/src/to-trpc-meta.ts so it can be passed directly to tRPC .meta() calls with arbitrary user-defined meta shapes.
  • Inlined test routers in packages/trpc/src/to-orpc-router.test.ts and packages/trpc/src/to-orpc-router.test-d.ts and removed the shared fixture to avoid cross-test coupling.
  • Restored the non-TRPCError rethrow test using a mutation that returns an async iterable whose iterator factory throws the original error.

⚠️ Nested lazy routers under plain object records remain inaccessible

A runtime reproduction confirms the issue raised in the previous review is still present: tRPC stores a lazy placed under a plain record (nested: { lazy: lazy(...) }) with the dot-joined key nested.lazy. lazyToORPCRouter assigns that key verbatim, so orpcRouter.nested.lazy is undefined while (orpcRouter as any)['nested.lazy'] is the Lazy. The existing deep lazy test only covers lazies inside lazy-loaded sub-routers, not this plain-record case.

⚠️ @trpc/server peer dependency still lacks an upper bound

packages/trpc/package.json:39 still declares "@trpc/server": ">=11.4.2". Because this package imports from @trpc/server/unstable-core-do-not-import, a future tRPC semver-major release could break the integration without a compatibility signal.

⚠️ batchIndex: 0 remains hard-coded

packages/trpc/src/to-orpc-router.ts:110-111 still passes batchIndex: 0 to tRPC procedures, so converted procedures will not behave correctly under the oRPC Batch Plugin.

ℹ️ Nitpicks

  • apps/content/docs/integrations/trpc.md:58 still uses z.ZodError, z.prettifyError, and z.flattenError without showing the imports (zod, ORPCError, TRPCError), so the error-formatting snippet is not copy-pasteable.

Pullfrog  | Fix it ➔View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

The latest commit resolves the nested lazy-router issue from the previous review. Type-check and all 15 runtime tests pass, and I found no new issues in this increment. This PR still carries unresolved Pullfrog feedback from the prior review, so it is not yet mergeable.

Reviewed changes — since the prior Pullfrog review at b38745d, the latest commit fixes nested lazy routers placed under plain object records.

  • Fixed nested lazy-router placement in packages/trpc/src/to-orpc-router.ts by splitting tRPC's dot-joined lazy keys with set from @orpc/shared, so orpcRouter.nested.lazy is now accessible at runtime.
  • Added/updated tests in packages/trpc/src/to-orpc-router.test.ts covering deep lazy-loaded sub-routers and lazies nested under plain object records.

Pullfrog  | Fix it ➔View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

@dinwwwh
dinwwwh merged commit b84477d into middleapi:main Jul 19, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant