Some notes on the tech stack for my side projects.
Goal
A pragmatic stack that is easy to maintain, specially it’s ecosystem, and has a broad range of needs covered by the community.
I want to quickly prototype, build PoCs and MVPs, and also be able to use the same stack on “production” if I decide to maintain the project.
Project management
Tracking progress, splitting projects into milestones, listing tasks, and writing. Notion and Obsidian cover everything here.
Frontend
A while back I wrote about what my tech stack should be. At that point I was still all in on the FP boat, and I still am to some extent. From migrating the Scarf site (Vue to Next.js/TS) and using PureScript Halogen on Listas I learned that a pragmatic and familiar solution beats a fancier one (fancier here means something with more type safety and maybe a more principled take).
Next.js is a state of the art framework for building frontend applications. And TypeScript is good enough when it comes to type safety and confidence that if it compiles it works, as long as the code you write follows some good practices (meaning as long as you work on it alone or with a team that shares the same mindset). The only thing that TS misses is pattern matching, although ts-pattern gets quite close.
The React ecosystem is way broader than Halogen one. This is a huge productivity boost.
Vercel is still the way to go when it comes to deploying frontend applications.
Backend
As per the backend, I’m torn between Haskell and Rust. I’m familiar with both and I like them for different reasons. While both are great for domain modeling and type safety, the former is annoying because of typed effects, the later is annoying to work with because of typed memory.
There are some things that are easier to do in Haskell, like parser combinators or modeling stuff with recursive data types. While there are some things that are easier to do in Rust like side effects.
When it comes to the community/ecosystem I think Rust is in a better state than Haskell, although Haskell is improving a lot in the last years.
Either Rust with a simple template like ndelvalle/rustapi (with PostgreSQL) or Haskell with Tie and postgresql-simple sound good. But having two options kinda defeats the purpose of sticking to a single solution and mastering it. Master your tools
One point in favor of Rust is being able to work with Nico. 🚀
For a database, I’m happy with the free tiers of ElephantSQL (or Mongo Atlas if, for some reason, I want or have to use MongoDB).
For deployment, fly.io is cool (although they are have a few outages these days, but I’m sure this is going to improve, same story as the early days of Vercel). Their basic pricing is affordable. $1.94/mo for a shared-cpu (1x) with 256MB of RAM. Dedicate CPUs are quite pricey though, however by the time I need that I’ll be making money from the project, most probably.
One negative side of fly.io is the requirement for public Docker images to deploy Haskell or Rust projects. But I have a nice setup around that. I could move the setup to GitHub Actions if I need automation.
Nice to have
- Template projects to quickly bootstrap things
- Shared libraries or code generation for the common stuff, as opposed to tweaking the code from the template on each project.
- Some sort of monitoring tool (Subilo / Jarvis?)
- Subilo needs some improvements to do deployments in a better way (eg. take arguments and pass them as environment variables)