Lessons learned from my June tiny project
I built a new tiny project in June named New Course Alert.
New Course Alert will send you alerts when new courses are released in subjects you care about.
New Course Alert will monitor ALL the online course providers:
It's a one stop shop to surveil all the courses being released.
On New Course Alert, currently I am subscribed to Development and Engineering. It's been a lot of fun getting emails every morning telling me about new courses in those subjects.
Over the next month, I plan to expand the number of course providers and to refine the subscriptions so users can more narrowly subscribe to just what they care about.
But as of today, the MVP for New Course Alert is done. You can signup and subscribe to subjects and get email alerts. While there is still lots to do, I'm pleased with how it's come along so far!
So first I'll go over some of the tech choices I made for my previous project Game Update Notifier. Then I'll go over the different tech choices I made for New Course Alert. And why.
I was able to reuse quite a bit of the code from Game Update Notifier in New Course Alert. Fundamentally they are both just scraping the web to detect updates and sending email notifications to users. They just happen to focus on two different domains, Gaming vs Education.
So Game Update Notifier was built using Django REST Framework (DRF) for the BE and Svelte for the FE.
I am extremely familiar with DRF, having used it in my day job for the past decade or so.
But it was my first time working with Svelte. I chose it because I was looking for something with less boilerplate than React.
Overall I really enjoyed Svelte. However, I found that the context switching between BE and FE was a bit annoying. You also have to deploy twice for most features, both FE and BE. And also, when you have the FE hosted on one domain and the BE and another, you have to deal with all that CORS stuff.
Also speed is a concern. Game Update Notifier is reasonably fast, with an overall performance of 78 on mobile from PageSpeed Insights. 78 is obviously not ideal but it's not too annoying.
(Part of the reason my implementation of Svelte is slow is just my own ignorance. I know for a fact my SSR configuration isn't ideal. That said, I don't want to spend a huge amount of time diving into the finer points of SSR and all that jazz with Svelte. I'd rather focus on the product.)
Lastly, I used Bootstrap 5 for the CSS library. Primarily because I was already familiar with Bootstrap (which hints at how long ago I did FE dev full time :)
So for New Course Alert, I went a different direction.
Inspired by Django Forge, I decided to just have the server render the HTML and send it to the FE.
In other words, it's just a stock, classic Django site. Pass DB data to Django Templates, have them render, and send them to the client.
The result is that there is almost no Javascript on the page. And hence no webpack build or any of that jazz. Also whenever I want to deploy, there's just a single simple deploy: the BE.
The one JS library I do use is HTMX. It was easy to figure out and it let me build a couple interactions that feel a lot like a Javascript SPA.
When I first started developing back in ~2010, server-rendered HTML seemed hopelessly antiquated and boring. I was all about AJAX and jQuery and Angular 1. Maximal Javascript!
Now I find server-rendered HTML to be elegant and useful. For a solo dev working on a tiny web project, it's kind of perfect. I can build and deploy and iterate on new sites crazy quickly.
Also, server-rendered HTML is fast. PageSpeed Insights gives New Course Alert a 97. And I didn't even have to do anything to make it that fast.
I even use Django Whitenoise to host the static assets rather than going through the fiddly bits to set up Django Storages with S3. Whitenoise is so easy!
Lastly, I used Pico CSS for the CSS library. I do occasionally miss some of the Bootstrap niceties. But with Pico, I like that I can just write some HTML, set the theme to dark, and everything just looks pretty good with zero configuration or effort on my part.
So younger me would complain here about scaling. "That's fine now. But it won't scale. You have to build it to scale."
Here's the thing about scaling though:
In my whole career, in all my projects, in all the companies I've worked for, scaling the client-facing Web UI has never been a big problem.
And I'm not just talking about my tiny projects. I'm also talking about successful, profitable companies, some of whom went on to be acquired.
Whether you render the HTML on the client device or on the server just doesn't matter in the grand scheme of things.
UNLESS you hit the explosive growth of an Instagram or Whatsapp.
But what a problem to have. You've won if you hit explosive growth like that. You can rewrite stuff and figure it out.
...
That said, I DID make two concessions to making New Course Alert scalable:
I did both these partly just for convenience.
With RDS, you get lots of DB setup / backup / rollback stuff out of the box.
And with the Load Balancer, you get HTTPS for free.
So yeah, these two choices, in addition to being convenient, also make it relatively straightforward to scale the app.
I can just spin up a second box and throw it behind the Load Balancer and scale horizontally.
Scaling servers that render HTML isn't hard. It won't make or break a project.
Before Product-Market Fit, speed of learning and iteration is everything. And for me personally, working as a solo dev on a side project, iterating on Django-rendered HTML pages is much faster than doing a JS SPA FE and REST JSON API.
That's why I chose classic Django for New Course Alert. And I couldn't be happier with the choice!
So yeah. If you haven't taken old school templates and server-rendered HTML pages out for a spin for a while, you might want to consider it. It's fun.