# Contributor handoff — trpc/trpc

> Canonical page: https://codevetter.com/unpack/trpc/agent-handoff

# Contributor handoff — trpc/trpc

Scanned commit 8b649ad874a8fe97c73962d4617912231b975736 (2026-09-17). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Read the procedure and HTTP core before editing. Tests run against source via Vitest aliases, but typecheck and consumers need pnpm build because packages ship dist built by tsdown. Keep adapters thin, put behavior changes in unstable-core-do-not-import, and add a regression under packages/tests. Do not treat examples or www as the library. OpenAPI fixtures are generated and checked in CI. Public types are the product, so signature changes are breaking even when runtime behavior is not.
- Files to read first: CONTRIBUTING.md (package map and the resolveResponse walkthrough), initTRPC.ts, procedureBuilder.ts, router.ts, http/resolveResponse.ts, http/contentType.ts, createTRPCClient.ts, and the adapter you are changing. The CONTRIBUTING page names those as the mental model for server, client, react-query, and next. — [CONTRIBUTING.md#L67-L113](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/CONTRIBUTING.md#L67-L113) [packages/server/src/unstable-core-do-not-import/initTRPC.ts#L217-L221](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/server/src/unstable-core-do-not-import/initTRPC.ts#L217-L221)
- Safe command set is pnpm install, pnpm build, pnpm dev, pnpm test <filter>, pnpm lint, and pnpm typecheck-packages. pnpm test 3085-style filters are the documented way to run one regression. Do not run publish-canary, publish-prerelease, or the release workflow unless asked. — [CONTRIBUTING.md#L9-L57](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/CONTRIBUTING.md#L9-L57) [package.json#L10-L37](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/package.json#L10-L37)
- Each of @trpc/server, @trpc/client, @trpc/react-query, @trpc/next, and @trpc/openapi sets eslint no-restricted-imports on its own package name. Inside a package, import sibling files relatively. Cross-package imports must use the public export, and client code reaches internals only through @trpc/server/unstable-core-do-not-import. — [packages/client/package.json#L17-L24](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/client/package.json#L17-L24) [packages/server/src/adapters/express.ts#L11-L13](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/server/src/adapters/express.ts#L11-L13) [packages/client/src/createTRPCClient.ts#L3-L16](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/client/src/createTRPCClient.ts#L3-L16)
- Vitest aliases point at src, so a unit test does not require dist. turbo typecheck and lint depend on ^build, and the e2e job runs pnpm build first. After a type-only change, run pnpm typecheck-packages; after a runtime change, run pnpm test with a filename filter before the full suite. — [vitest.shared.ts#L28-L36](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/vitest.shared.ts#L28-L36) [turbo.json#L38-L51](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/turbo.json#L38-L51) [.github/workflows/main.yml#L29-L47](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/.github/workflows/main.yml#L29-L47) [.github/workflows/main.yml#L152](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/.github/workflows/main.yml#L152)
- Put new behavioral regressions in packages/tests/server, matching existing names (regression issue tests, batching, streaming, websockets). Colocate type-level tests next to the module when that is the local pattern (procedureBuilder.test.ts, router.test.ts). React hook tests belong in packages/react-query/test. — [CONTRIBUTING.md#L49-L51](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/CONTRIBUTING.md#L49-L51) [packages/server/src/unstable-core-do-not-import/procedureBuilder.test.ts](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/server/src/unstable-core-do-not-import/procedureBuilder.test.ts) [packages/react-query/src/index.ts#L1-L8](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/react-query/src/index.ts#L1-L8)
- Do not hand-edit packages/openapi/test/routers. CI fails the unit job if that tree is dirty and prints the exact command pnpm -C packages/openapi codegen. @trpc/openapi is version 11.19.0-alpha, so treat its API as unstable relative to the 11.19.0 libraries. — [.github/workflows/main.yml#L83-L93](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/.github/workflows/main.yml#L83-L93) [packages/openapi/package.json#L2-L5](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/openapi/package.json#L2-L5)
- Router keys then, call, and apply throw at createRouterFactory. Procedures are functions; isProcedure uses typeof === 'function', which is also why lazy loaders are stored separately. Do not add callable properties that would be mis-detected as procedures. — [packages/server/src/unstable-core-do-not-import/router.ts#L208-L221](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/server/src/unstable-core-do-not-import/router.ts#L208-L221) [packages/server/src/unstable-core-do-not-import/router.ts#L361-L365](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/server/src/unstable-core-do-not-import/router.ts#L361-L365)
- Never invoke a procedure as a normal function from application code. createProcedureCaller throws a fixed message unless opts contains getRawInput. Server-side calls go through createCallerFactory. Client calls go through the proxy. — [packages/server/src/unstable-core-do-not-import/procedureBuilder.ts#L628-L679](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/server/src/unstable-core-do-not-import/procedureBuilder.ts#L628-L679) [packages/server/src/unstable-core-do-not-import/router.ts#L449-L480](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/server/src/unstable-core-do-not-import/router.ts#L449-L480)
- isDev and isServer are environment gates. isServerDefault is true when window is undefined, Deno is present, or NODE_ENV is test, or JEST_WORKER_ID or VITEST_WORKER_ID is set. Forcing the server build into a browser bundle requires allowOutsideOfServer and will throw otherwise. — [packages/server/src/unstable-core-do-not-import/rootConfig.ts#L20-L26](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/server/src/unstable-core-do-not-import/rootConfig.ts#L20-L26) [packages/server/src/unstable-core-do-not-import/initTRPC.ts#L170-L178](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/server/src/unstable-core-do-not-import/initTRPC.ts#L170-L178)
- Examples and www are not safe refactor targets when changing the library. Examples pin workspace packages and demonstrate patterns (some insecure on purpose, such as the mock GitHub provider and empty Prisma context). www/vercel.json redirects are easy to break by renaming a docs slug. — [examples/next-sse-chat/src/server/auth.tsx#L12-L23](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/examples/next-sse-chat/src/server/auth.tsx#L12-L23) [examples/next-prisma-starter/src/server/context.ts#L13-L28](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/examples/next-prisma-starter/src/server/context.ts#L13-L28) [www/vercel.json#L1-L8](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/www/vercel.json#L1-L8)
- Peer dependencies are exact: @trpc/client requires @trpc/server 11.19.0. Shipping a server change without bumping the peer, or testing with mismatched workspace versions, will not match what npm users install. prepack and version run tsx scripts/version.ts. — [packages/client/package.json#L117-L120](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/client/package.json#L117-L120) [package.json#L28-L30](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/package.json#L28-L30) [lerna.json#L2](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/lerna.json#L2)
- The widest blast radius is the procedure and router generics (ProcedureBuilder, DecorateCreateRouterOptions, DecoratedProcedureRecord). They are copied into every client package. A type-only break will fail pnpm typecheck-packages and the example typecheck step even when Vitest is green. (inferred) — [packages/server/src/unstable-core-do-not-import/procedureBuilder.ts#L187-L196](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/server/src/unstable-core-do-not-import/procedureBuilder.ts#L187-L196) [packages/server/src/unstable-core-do-not-import/router.ts#L230-L244](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/server/src/unstable-core-do-not-import/router.ts#L230-L244) [packages/client/src/createTRPCClient.ts#L98-L120](https://github.com/trpc/trpc/blob/8b649ad874a8fe97c73962d4617912231b975736/packages/client/src/createTRPCClient.ts#L98-L120)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
