Why I’m learning Drizzle, a typesafe ORM

The React ecosystem is moving to tools and paradigms that will strongly benefit from typesafe ORMs in the JS/TS ecosystem.

As a long-time Django + React user, I’m taking the time to learn Drizzle.

It’s going to be a journey.

Here’s why I’m embarking on it.

Investing in things that don’t change

I believe in investing in the things that won’t change, so it might seem weird to be learning a new ORM right now.

“Dan, this is just the trendy technology of the day. Here today, gone tomorrow.”

That’s fair - but I see learning Drizzle as an investment in three things that (I think) won’t change: type safety, React Server Components, and SQL.

For context, I’ve historically used Django and SQL Alchemy. (preference for Django)

Type Safety

In my experience, type-safety massively boosts productivity and maintainability for codebases. I’m not just talking ten years in, I’m talking 12-18 months in, or even less.

I’ve worked with SQL Alchemy and Django quite a bit in the past, and bugs made their way into production all the time that could have been caught by a statically typed language.

Could you catch these things with unit tests? Yes.

Could you add type annotations into your Python codebase to catch these kinds of things? Also yes.

But here’s the thing: it’s pretty common to have untested codepaths. And sometimes adding type annotations is not fully supported by certain libraries.

The tooling is built for it

PaaS / Serverless / Vercel

If you write React code and are starting a personal project today, there’s a solid chance you’re using NextJS and deploying to Vercel.

The experience is honestly hard to beat.

And this means that your “server-side” code is actually running in serverless functions that Vercel hosts for you.

Django and SQL Alchemy were built before this deployment paradigm even existed. I believe there are ways to deploy your Django code to serverless functions — but you’re kind of fitting a square peg into a round hole.

I can realistically say that I’m not going to do that.

The alternative, then, is to run my Django code elsewhere and have it expose an API to my frontend.

...and now you’ve got weird CORS issues to deal with, which is always a pain.

...and also maybe you should just serve your React site from the same place that you’re hosting your Django backend, right? Maybe?

Or... didn’t you kind of want to use Vercel?

Suddenly, even getting your whole system to “hello world” feels like an uphill battle.

Which is fine. We’ve been here before and have a Dropbox Paper note on it somewhere...

But here’s the thing: my “hello world” setup shouldn’t require a deep-dive into my personal wiki.

I shouldn’t have to futz with nginx configuration or CORS issues. I want it to just work.

React Server Components

And it’s not just the deployment experience that’s better if your backend logic lives in your NextJS codebase. (or equivalent meta-framework)

With React Server Components, using a JS (or TS) ORM is going to make a big difference.

Writing database queries in server-rendered component will become the norm soon.

...and if you have a Django backend, you’ll probably have a clunky developer experience (DX).

I’m speculating
I’m speculating

I haven’t actually tried writing React Server Components with a Django backend, so take this with a grain of salt.

If you have, I’d love to hear how it went.

SQL-forward

It feels like the learning journey for an ORM has two main parts:

1. Learning to use the damn thing

First, you learn how to even use it.

You figure out all the weird quirks — like the fact that your validation logic doesn’t get called when you’re creating or updating more than one object at a time. Weird!

And then eventually you’ve figured that part out.

...and now, hopefully, you’ve built a product with lots of users. And, what’s that? Some of them are complaining about slow pages?

Oof. Time for the second phase of the learning journey...

2. Performance

Performance tuning is the part where you undo all of your sins from the first part.

Remember how your custom model validation only got called when you saved one record at a time?

Yea... so you have a bunch of for-loops that all call MyModel.save() over and over.

And each of those is making a call to your database! So it’s brutally slow.

Or maybe one of your teammates wanted to fetch all of the blog posts for a list of authors, so they used a for loop:

1posts = []
2for author in all_authors:
3 posts += author.posts

...but it turns out that every time you reference author.posts, you’re actually making a database call to fetch those posts.

So... what’s your point, Dan?

The point of all this is two things:

Learning SQL vs some random ORM’s intricacies

I’ve noticed over time that I actually don’t want much “magic” and fancy stuff from my ORM. It seems like Drizzle is taking a “less is more” approach. Appealing!

And, in particular, the tool seems to encourage users to not be afraid of writing SQL. That’s great! I’ve been SQL-curious for a long time, and I’ve been slowly getting better at it.

This seems like a great opportunity to just go all-in on it. (or “mostly-in” at least)

SQL is here for the long-haul, so it would be an investment in something that’s not going to change anytime soon.

Plus, LLMs are particularly good at writing SQL, so I think they’ll be helpful in the learning journey.

Surfacing performance issues sooner

Maybe this is wishful thinking...

...but I have a hunch that “thinking in SQL” vs “thinking in Django” will make it easier to write more performant code.

Many of the footguns I’ve encountered in the past have to do with “syntactic sugar” that ORMs provide for making database queries on your behalf. (like the author.posts example above)

Sure, these seem nice upfront, but it makes it too easy — I think — to accidentally write low-performance code.

Caveat: Performance vs Impact
Caveat: Performance vs Impact

I’ve always felt that focusing on performance should happen in the context of focusing on impact.

What does the performance of your code actually mean for your users / business?

If it doesn’t really matter, then you should strongly consider moving onto things that do!

That said, if you can bake performance into your daily work without much sacrifice, you may as well.

Conclusion

Ultimately, I want to be really good at building products that help people.

My tooling should facilitate that.

The DX of doing everything within NextJS and deploying on Vercel is enough to sell me on using Drizzle. And the fact that it’s SQL-forward is a huge bonus.

As far as the learning process itself, my plan is to build a bunch of stuff with it.

When I encounter something weird or quirky, I’ll take note of it and make time — either immediately or later — to explore it in more detail.

Stay tuned to see what comes next.