ts-rest is no longer maintained. Forks are welcome. Read the notice.
ts-rest

FAQ

Frequently Asked Questions

Who uses ts-rest? 💚

ts-rest grew out of production use at the original maintainers' companies, including @ts-rest/react-query and @ts-rest/nest at Onsi. This history does not imply ongoing maintenance or support.

I founded ts-rest primarily to solve the problems we faced inhouse, the difficulty to introduce cross-stack type safety in an existing large codebase, incrementally.

Star History Chart

👆 Any by the looks of it, we're not alone!

Is this project actively maintained?

No. ts-rest is no longer maintained. There are no planned releases, bug fixes, security updates, or support. Existing releases, source code, and documentation are available as-is.

I no longer have the time or capacity to maintain the project or run its community. I'm sorry for the long silence, and grateful to everyone who used or contributed to ts-rest, and to everyone who sponsored my work.

Will V4 be released?

There is no planned V4 release. The V4 branch and draft PR contain unfinished work that independent forks can build on. They are not a supported release.

The last stable release is 3.52.1. The 3.53.0-rc.1 prerelease was never promoted to a stable release and has known compatibility issues with stable Zod 4.

Can I fork or contribute?

Yes. Independent forks are welcome, including forks of individual adapters, under the existing MIT licence. You do not need approval from the original maintainers to continue the project independently.

The upstream project is no longer accepting contributions or providing support through GitHub or Discord. Please direct new work to your own fork or another independently maintained project.

How does this compare to tRPC? 🤔

tRPC is great - KATT (Alex Johansson) and all the other maintainers have done some amazing work, and for applications with a single Next.js app, or an express server only consumed by TRPC clients, I whole heartily recommend using tRPC! Also I have undoubtedly taken inspiration from tRPC for ts-rest.

One of the biggest differences between tRPC and ts-rest is that tRPC defines your API implementation as the contract, for some use cases it is beneficial to have a separate contract to represent the API.

One example of this is with NX, in NX you can rebuild only "affected" packages, however, if you export your contract (e.g. tRPC) from the backend, your front end will need to be rebuilt as well. ts-rest negates this issue by allowing (in NX) for a library for the API contract to be created, this then means the only case in which the front and backend need to be rebuilt is when the contract changes.

REST(ish)?

REST(ish)? REST is a term the industry (as a whole) has used incorrectly for many years now. In recent years, it is used as a synonym for HTTP requests over a API. Read more here

ts-rest allows you design an API as you would "normally", e.g. GET, POST, PUT, DELETE etc. to /posts, /posts/:id, /posts/:id/comments etc. whilst providing these endpoints to the client as RPC-type calls like client.posts.getPost({ id: "1" }) or client.posts.getPostComments() in a fully type safe interface.

tRPC structures your API as RPC calls such as /trpc/getPosts or /trpc/getPostComments etc, this provides an arguably simpler API for the client implementation, however, you loose the predictability of REST(ish) APIs if you have consumers who aren't in TypeScript (able to use @ts-rest) or public consumers.

tRPC has many plugins to solve this issue by mapping the API implementation to a REST-like API, however, these approaches are often a bit clunky and reduce the safety of the system overall, ts-rest does this heavy lifting in the client and server implementations rather than requiring a second layer of abstraction and API endpoint(s) to be defined.

Why is my TypeScript intellisense slow? 🐌

You'll need to enable strict in your tsconfig.json:

  "compilerOptions": {
    ...
    "strict": true
  }

If you're using a monorepo, make sure this is applied at the project level. Example:

./apps/some-app/tsconfig.json

^ make sure strict is true here

If you cannot use strict entirely, you'll need to at least enable strictNullChecks.

This is required as part of Zod. See why here.

It's still quite slow

If you've correctly enabled strict and strictNullChecks, and you're still experiencing slow intellisense, you may be approaching the point at which (pre tsgo) Typescript starts to feel fairly sluggish.

  1. Try split up your clients/contracts We've had some success with splitting up our clients into different domains, for instance postClient, userClient, authClient etc. this splits up the client into smaller chunks, which can help with intellisense performance.
  2. Move to a more tsc friendly validator Zod 3 was fairly renowned for it's affect on intellisense in large codebases, Zod 4 improves greatly on this, but ts-rest's Standard Schema support only shipped in the unfinished 3.53.0-rc.1 prerelease, which has known compatibility issues with stable Zod 4.
  3. Utilise monorepo tooling - NX (and probably others) offers some ways to pre-compile modules, emitting .d.ts files for your modules, this could be a good way to speed up intellisense.