from Hacker News

TRPC: End-to-end typesafe APIs made easy

by namelosw on 5/6/22, 2:50 PM with 56 comments

  • by colinmcd on 5/6/22, 4:34 PM

    I wrote the initial proof of concept for tRPC a little over a year ago (though I'm no longer involved in the project). Seems like there's some confusion about how this works. A more complete description is available here[0] below but I'll put a brief explanation below as well.

    - It's designed specifically for a full-stack TypeScript app. Your API is implemented as strongly typed server-side functions.

    - The input type is specified using a schema library like Zod or io-ts.

    - TypeScript infers the return type of these functions.

    - You can then import the type signatures of your functions into your client. Just types, no runtime code! This is safe in typescript with the `import type` syntax. tRPC uses those type signatures to provide a typesafe client API, basically an SDK for your API. There's no codegen happening - the client uses TypeScript generics to provide a set of strongly typed "proxy functions" that can be "called" on the client. These proxy functions execute HTTPs requests under the hood: https://trpc.io/docs/rpc

    The point is to avoid the boilerplate, codegen, and lack of DRYness associated with building a strongly typed API in TypeScript. You can do this with GraphQL but it relies on code-generation, requires complete buy-in, and (IMO) doesn't provide a great developer experience. TypeScript has a native way of representing types, so the goal is to avoid an intermediate representation (in the form of an OpenAPI spec or GraphQL schema) entirely. As you update your server code, the client's type signatures update instantaneously.

    Another important goal is to make it easy to write DRY code when building APIs. Without tRPC, it's common to manually provide type definitions for the results of API calls. But those definitions can easily get out of sync with your actual server code. tRPC infers types from your code itself and provides a typed interface for your API thats doesn't require any manual type annotations.

    [0] https://colinhacks.com/essays/painless-typesafety

  • by mhoad on 5/6/22, 10:51 PM

    Not looking to actively bash anyones work here but I’m really confused on the value proposition here over something like gRPC which has a lot of substantial advantages from speed, to wide cross language support and has been battle tested in the most extreme scaling scenarios possible.

    A truly huge amount of time, money and optimization went into a project like that and has been proven to work well for years now.

    The JS ecosystem confuses me with things like this regularly just the other day I was watching a video where the lead devrel person from Vercel was trying to explain “edge functions” to a senior backend engineer that started falling apart under the most rudimentary questioning so much so that in the video they have this awkward hard cut and they rush to wrap up the interview. Link if anyone is interested https://youtu.be/yuxd2kurpzk

    This gives me kind of similar vibes in that I just don’t really get the use case here unless it’s to intentionally stay strictly in the JS ecosystem for some reason?

  • by eandre on 5/6/22, 4:18 PM

    If you want a similar experience to this but more optimized for backend development using Go, I've been building https://github.com/encoredev/encore for the past few years!
  • by gavinray on 5/6/22, 4:10 PM

    You can do this with GraphQL too:

    https://genql.vercel.app/

    https://github.com/graphql-editor/graphql-zeus

    I did a 5 min talk about these newer breeds of codegen tools (where it's a single client SDK that does automatic return type inference based on the input args), they're really neat:

    https://www.youtube.com/watch?v=7n3MeMFHiMk

    (Skip to 2:14 to see the autocomplete/type-safety)

  • by evantahler on 5/6/22, 4:42 PM

    This is one of the best things about typescript. You can do this kind of thing without much special tooling at all - https://www.evantahler.com/blog/post/2020-10-16-typescript-f...
  • by theobr on 5/6/22, 8:10 PM

    tRPC has been a lifesaver for us at Ping.gg

    Never had such a seamless experience building and deploying “full stack” apps. Multiple classes of bugs just, like, don’t happen now?

    Helped build up a lot of the GraphQL tech at twitch, and I still love it, but man do I not miss all the work maintaining the “contract” between front and back. I know we will have to move off tRPC eventually, but I’m hyped at how far it’s taken us already

  • by awhitty on 5/6/22, 8:28 PM

    This project looks interesting! I have used a similar project called tsoa [1] and have appreciated that it generates an OpenAPI spec that can be consumed readily by many other clients, even outside the JS ecosystem. Does TRPC have plans for a similar feature set?

    [1] https://tsoa-community.github.io/docs/

  • by stickfigure on 5/6/22, 3:25 PM

    The docs don't say anything about the wire protocol - is this based on REST/JSON, or something proprietary? If proprietary, is it spec'd and documented? Support for implementations in other languages?
  • by jeroenhd on 5/6/22, 4:06 PM

    Only supports using Javascript/node servers it seems, so sadly it's not really usable for me.

    The type exchange seems to rely on shared code between the frontend and the backend to exchange types, rather than using schemas like other systems.

    Not implementing server-side events seems like a shame because they're a very capable mechanism for subscriptions without resorting to websockets.

  • by markoutso on 5/6/22, 8:08 PM

    I am really not getting this. If you run Typescript on both ends, can't you just share the source code that defines the types?
  • by bradrn on 5/6/22, 3:26 PM

    I’ve never used this, but it looks like a very similar idea to Haskell’s Servant library [https://docs.servant.dev/en/stable/]. Could someone who knows more enlighten me as to how correct this comparison is?
  • by jre on 5/6/22, 4:39 PM

    I like this idea very much. Shameless plug and I don't want to be the Rust fanboy, but I've played with something similar in Rust:

    https://github.com/julienr/liveboard-rs

    Basically it uses actix for the backend and yew (Vue-like rust frontend framework) for the frontend. This enables one to share types (and helper functions) between both, which is great:

    https://github.com/julienr/liveboard-rs/blob/master/shared/s...

    That being said, I think maturity-wise, Typescript is probably a better bet for this right now, so I'll definitely look at trpc for $dayjob.

  • by alexdotjs on 5/6/22, 6:55 PM

    Awesome to see my lil' baby on the frontpage!
  • by tantalor on 5/6/22, 3:58 PM

    > without schemas

    What is a type definition if not a schema?

  • by arpinum on 5/6/22, 9:08 PM

    I'm not seeing the appeal of this over Smithy, which can target multiple frontend and backend languages. What am I missing? What is wrong with codegen tools? Especially when they help you design strong contracts upfront, rather than ad-hoc API design as their demo shows.
  • by janpot on 5/6/22, 5:38 PM

    Nice! I wrote something similar for Next.js a while ago. The pattern is so much more ergonomic than everything else I've used before.

    https://npmjs.com/package/next-rpc

  • by kristiandupont on 5/6/22, 5:51 PM

    I recently gave a talk about our experience with tRPC. So far it's looking very promising!

    https://www.youtube.com/watch?v=k1TCueEhhJo

  • by darepublic on 5/7/22, 3:01 AM

    interesting this came up because I'm looking to do exactly this -- but my first instinct is simply to share declaration types from my server with client as a dependency
  • by hardwaresofton on 5/7/22, 12:31 AM

    > Currently GraphQL is the dominant way to implement typesafe APIs in TypeScript (and it's amazing!).

    Disagree here and it’s a bit disconcerting to see this as an opening premise.

  • by vander_elst on 5/6/22, 5:56 PM

    How does this compare to gRPC? That the wire protocol is actually http+json instead of binary? I wasn't able to find much on their website
  • by hegem0n on 5/6/22, 4:38 PM

    I love this. This is the future
  • by AvImd on 5/6/22, 11:07 PM

    Does this work with NestJS?
  • by Vosporos on 5/6/22, 8:07 PM

    you can't have type-safety with an unsound type system, silly.
  • by lowwave on 5/6/22, 6:48 PM

    interesting. Kinda like fastify json schema.