Alternative title: "How I stopped worrying about the stack and embraced Good Enough"
What I am, and am not talking about
I want to make one thing clear: I am not talking about enterprise app that must scale to millions of requests per second. I'm also not talking about places where you need the smallest possible resource footprint while getting the job done.
For both of those cases you will find languages and tools much better suited for the task at hand. Go, Rust, C, Java, ~~Uppercase Java~~ C#... All of those are likely to give you a better experience than JS.
I'm talking here just about side projects that may or may not ever be finished. This also applies to small one-off tools that you know won't be used for long, though to a lesser extent.
Side projects
I'm a programmer. I enjoy writing code. I love creating things. If you're anything like me, you probably started dozens of side projects, and know these thoughts too well:
- "I need a thing that does X, Y and Z, but all the existing solutions suck/only do X and Y but not Z. Time to make my own"
- "I wanna learn more about X. I'm gonna make my own [X-consumer] to learn it"
- "Why is this so bad, it can't be that difficult to make a good X"
Don't get me wrong, side projects are great. They are amazing for learning, and amazing to fill a specific need. I especially recommend starting side projects to new programmers, as that's the quickest way to learn how to do anything.
I still remember my first "real" project I did as a teen. It was an extremely simple CMS written in Java, that allowed people to register, log in, comment, and the authors could create posts. It was utter shit, but it was mine, and that feeling of having made something is the biggest reason I'm still programming all these years later.
And it taught me so much - http, cookies, why you shouldn't store plaintext password, principles like "locked down by default", how to rawdog SQL joins... So many lessons that help me to this day, and all because I thought it would be easy...
Obligatory AI tangent
You might ask, "but why not use AI to make the thing?" And the answer is literally the first line in this section. I make side projects because I want to make them, not have them made. I'll write a bigger post about what I do or don't like about AI at some point.
The decision paralysis of modern dev world
Up until relatively recently, any time I was thinking of starting a new side project, more often than not I was stopped on the very first question. What tech stack should I use? Do I go full enterprise with Spring Boot + Postgress + Angular? Go/Gin/Templ + HTMX + SQLite? Finally try learning Rust? Go full soydev with Next.js? Or perhaps something else?
So I start researching. What is currently popular in dev world? What do the recruiters look for? Do I want to use something I know, or something completely new? An hour or two passes, and I leave before even writing a single line of code. At that point I'm bored, maybe frustrated, and I hate the modern dev world.
Enter Bun
Something you should know about me. For years I've been a minimalist. I write everything in Neovim. I use Arch BTW with DWM as my window manager. Electron apps are the bane of my existence, NodeJS should burn, and NPM was a mistake.
But then something new came along - Bun. I'll admit, I was very skeptical at first. It promised speed. It promised good APIs. It promised to make everything better. Nothing I haven't heard any time a new hot JS bundler/framework/library/whatever came out.
A couple months ago I needed a very simple tool at work - something I could deploy on my server, make it log http requests in a table, and have our software shoot requests at it, just to make sure we're sending everything correctly. I decided to give Bun a try.
I quickly installed the latest version, ran bun init, and fully expected to have to look for some libs - a http server that's not Express, SQLite, bundler, React... Imagine my surprise when Bun asked me if I want to use React, and if I want Tailwind, then it generated a whole frontend and backend with HMR and everything I'd have to install myself. A quick glance at the docs and I learnt it even has a built-in handler of SQLite databases.
Instead of wasting an hour on boilerplate, I had a working thing in 30 minutes. And the best part - writing it was fun. I didn't have to think about arcane APIs, instantiating an AbstractSingletonConfigurationBuilderSingletonFactory, writing 500 lines of YAML to define a database connection... None of that shit. Just the problem I had to solve and enough integrated APIs with sane defaults to solve it.
My new tech stack
Since discovering Bun, I did a couple side projects and refined my tech stack. At this point I know what packages I need for specific things:
- Bun as the bundler, transpiler, package manager, and backend
- SQLite for serverside persistence; no ORM because I don't do advanced enough things for the mental overhead to be worth it
- Generating basic SQL statements is actually a great use of AI. It can generate a perfectly valid
INSERTandSELECTgiven a TS interface, and a typical CRUD app doesn't need much more
- Generating basic SQL statements is actually a great use of AI. It can generate a perfectly valid
- React on the frontend
- React Query so I don't have to deal with
useStateanduseEffectshit just to get data from the server - Tailwind instead of CSS
- Cache Manager for the rare case where I need to cache something (Google API has shit limits for free tier)
- Gitlab CI for building and Docker for deployment on my own server
I call it the ADEQUATE stack. No, it's not an acronym, just a description. And it is just that - adequate. Not perfect, not universal, not great. Adequate. It gets the job done.
But why not something better
You know, if I did a bunch of research I could probably come up with a better stack for each use case. But most of the time it's not worth it. I could use ADEQUATE and make the thing (mostly) working (mostly) correctly, or I could waste a lot of time and risk never even starting. Something that's done poorly is infinitely better than the potentially perfect thing that's not even half way done.
JS has a lot of issues. React has a lot more. But the ADEQUATE stack has one major upside that a lot of other stacks can't replicate - I can shit out good enough code at insane speeds. For side projects, there is nothing better than that.
We can argue about performance, scalability, using workers and serverless runtime... None of that matters. ADEQUATE is meant for side projects that will have five users at most. The cheapest VPS you can find will be more than enough.
TL; DR
Don't overcomplicate your projects. Shit out code and be happy with finished product