3 minutes
Fully-Typed Typescript Stack
Introduction
Type safety is crucial in programming because it helps catch errors at compile-time rather than runtime, ensuring early detection and prevention of potential bugs. I’m sharing the stack that I’m using both in frontend and backend to achieve a fully-typed tech stack.
Frontend
UI Library / Framework
My pick for this is React. Having tried the big 3 frontend frameworks, it’s the only one that works very well with Typescript without the need for installing hacky extensions just to work well with your editor.
Router
For the router, I picked the new library in town TanStack Router. The sole reason is for it’s typesafety. No more searching and replacing when refactoring routes.
Fetching
For fetching stuff from the internet, I just use the vanilla fetch API functionality available natively in your browser and also the TanStack Query for managing data.
Forms and Validation
For this, I use a combination of react-hook-form for the form library and I use typebox for validation. Both are stitched to work together by @hookform/resolvers. This libraries allows me to have fully typed forms and validations.
Backend
Runtime
The runtime I picked in this stack is Bun. It just works out of the box with typescript
without installing additional compiler like tsc
just to compile and run your typescript code. It’s also
very fast and I can attest to it’s performance compared to Node. On top of that, it also has a very fast
testing suite that is very similar to jest but much faster. This also serves as the build tool for the backend
Server
For this, I picked Elysia. The reason is it’s fully typed compared to other libraries and
frameworks and it’s also very simple compared to something like nestjs
. It also works on Bun out of the box
and heavily supported it.
Database
For the databse, I picked Keysley for it’s simplicity compared to alternatives. It’s just basically
knex
but for typescript. To generate the types for the database, I use it’s cli tool kysely-codegen.
I did not use ORMs like TypeORM
or Sequelize
as they can be pretty hard to work with once the queries
start to get complex. Here’s a good blog post
on why it’s a bad idea.
Stitching Frontend and Backend API
Standard
I’m just using regular REST for its simplicity. For the API standard, use OpenAPI. It will allow you to generate types for your frontend.
Backend API Types
To make the consumers of this API have documentation and provide them the capability to generate types, I’m using the Swagger plugin in Elysia.
Frontend API Types
For the generating API types, use open-api-typescript with the combination of openapi-fetch. This is the simplest combination of libraries I can muster and I’m pretty happy with this.
Summary
- Frontend
- React
- TanStack Router
- TanStack Query
- react-hook-form
- typebox
- Backend
- Elysia
- Keysley
- Bun
- API
- OpenAPI
- open-api-typescript
- openapi-fetch
- Elysia Swagger
Conclusion
I’m satisfied with the stack, which is fully typed, but there’s some ’type fatigue’ from coding numerous types. However, it’s worth it to prevent errors, especially in large and complex projects.