Trying out a new stack: my experience working with tRPC and Drizzle on my Next.JS project
Tags: nextjs, typescript, postgres, trpc
Published: 2024-07-02 02:26:07

Recently I started working on a side project and I wanted to make it a fullstack typescript application. I decided to use Next.JS to take advantage of the tools already included in the framework(e.g. router, rsc, caching, etc.). On top of that I added two amazing libraries that make an excellent usage of **Typescript**: `tRPC` and `drizzle`, I want to talk a little bit about my experience working with them.

### [Drizzle](https://orm.drizzle.team/): a typescript ORM
There are a lot of _ORM_ and query builders available for Node.JS, you might have used or heard of packages such as Prisma, Knex, Sequelize or Typeorm. All of those will help you connect to a database, create your tables and run your queries, some of them will even let you define the entity types for your schema. What drizzle does different is the way it takes a big advantage of the type system Typescript offers.

The first thing I noticed when I started working with drizzle is how easy it was to define the schema for my tables. I didn't had to setup annotations or manually define the type for each column. Another thing that I found super helpful is the ability to reference the columns using a `camelCase` style while still defining the column name as `snake_case`, making easier to make manual queries. See the example below:

![Code example of drizzle schema](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mont3ywa38e1isi42fi1.png)

I am defining an users table with 3 columns with different types, notice how the object keys are defined using the `camelCase` style and in the first parameter of the drizzle constructors(`varchar`, `date`) I'm defining the name that will be used internally. Using drizzle defining the schema like this will automatically give you types, for example when you define a `varchar` column the type inferred will be `string`. See below:

![Code example of the inferred types on drizzle](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6hkvfb3pfanm2s7eisif.png)

As you can see all of my types are already defined by drizzle.

Drizzle have a big set of functions that facilitate building typesafe queries, they offer a full solution for making unions, joins and other common sql operations. It is also worth mentioning the magic `sql` operator that let you write your own query in case you need to.

If you want to learn more take a look at their [docs](https://orm.drizzle.team/docs/overview)

### [tRPC](https://trpc.io/): you might not need swagger 🤷🏽‍♂️
One of the difficult parts of working with frontend is when you need to define what comes back from the server. One of the solutions available is to use swagger to document your api and choose between a lot of libraries that can turn the swagger document into a client that handles the calls to your server. A problem that might arise from doing this is how accurate your documentation is as changes are made to the implementation on your server.

`tRPC` is a solution for fullstack applications that use Typescript. It make typesafe easy. The types of the inputs and outputs of your `procedures` are defined in just one place and you don't even need to explicitly create them, they will be inferred. By having all the server types defined in the actual code that is running in the server it is impossible to create inaccurate type descriptions. Below is an example of a call from a react component to a server procedure, notice how the types are already defined:

![Code example of using tRPC mutation on a react component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9vhsaxvv3sbb753vv3s4.png)

Is worth mentioning other two libraries that work really well together with tRPC: `zod` and `react-query`. With `zod` you can at the same time define a schema type and validate it against the actual value, making `mutations`, for example, much easier to validate. `react-query` is the missing piece for working with promises in React, and tRPC has a really good wrapper around it so that you can easily use your queries and mutations on your components.

Please note that this only work if you are working with a fullstack Typescript application, if you are working with different languages there is nothing tRPC can do for you. Keep swagging 🕺🏽

### Conclusion
Working with typescript nowadays days feels mandatory when working with javascript, as it improve the developer experience and avoid silly typing bugs, and working with tools that have Typescript at their core is the ultimate way to make the best out of it.