179 karma · joined October 23, 2015
Nothing I have ever used has a comparable dependency tree nightmare.
1. Locality of behavior - the classes are the description of the style once you know tailwind, and they live where the thing they're styling is. I can look at a template and know pretty well how it is going to look without having to go lookup a sites personal bespoke CSS and match what's written there to the markup.
2. It's the same classes as you move from project to project. I have tons of small one-off apps I maintain, all using tailwind and I don't have to figure out the custom CSS classes and their meanings. It is a knowledge set that reduces friction between projects and I really need things that reduce cognitive load like that.
3. No dead CSS. There are tools to help with this in regular CSS but I just don't have to think about it with tailwind and that's nice. I work on my templates and the CSS is updated and minifed on the fly without extra steps (or unnecessary CSS).
4. Easy to build a personal component library that doesn't also require relevant CSS to be bundles with it. For me this one is pretty great. Thanks to template engines (for me it's Django's, but Jinja or others are grand too) I have a simple place to pull components (really just template partials) and widgets I've made and they just work because the underlying classes are the same. There are some exceptions around color schemes and the like but now all my little components take a colour scheme arg and voila, no proballo.
I think the key here is that a description of the visual is embedded in the markup. That lets the actual mark-up delivered to the front-end describe pretty much the whole kit. With server-side rendering ( I use HTMX ) I can even write unittests that responses contain expected markup, including CSS classes (I built a few helper assertions that all of my test suites use) which gives me some interesting checks.
I really ultimately don't think there is one correct way to do things. The things I value may be utterly irrelevant to another developer.
Or when I'm working two contract gigs. I can spec things out for one and turn it loose and trust it. Then work more closely with deepseek on the other project.
As for FastAPI bring a mistake - that's an overgeneralisation to be sure. It has it's uses.
My first issue is that it falls into the same kind of small footprint as Flask. Every Flask project I work on slowly reinvents Django via a combination of plugins of varied quality and custom code/plugins. Get some Auth plugins, build step for manifest static files, add in Jinja2, grab an ORM like SQLAlchemy (or hopefully PeeWee), a migration system, test runners with fixtures/dB integration and rollback and on and on and on.
FastAPI is operating more at that level but also adds the often unnecessary complexity of async. In Python this is a cooperative setup meaning you have to yield to the event loop yourself (otherwise despite being "async" it blocks). Plus with a webapp all async often does is let you hammer your services (i.e. dispatch more queries to your poor DB) harder. The actual performance improvements don't manifest so much at scale as people often think. Plus you end up with a whole second set of ways to call functions and... makes me pine for gevent.
There are absolutely cases for this kind of async, even in webapps, but it's often not actually that helpful in places that it's used (and doesn't actually need to be everywhere). Good development imo means picking the right tool for the job rather than jumping on hype trains.
MongoDB is webscale!!
I went from jQuery to a brief dalliance with Angular to HTMX+_HyperScript. Everyone wants full stack Devs to use react and struggle eternally with insane dependency trees and challenging client side state management.
I like to build things that can be maintained in perpetuity by small teams.
So I'm not very marketable.
But most of all, any comparison is going to be silly. Photoshop has lots of amazing features and in sure is better in a technical comparison to Gimp in many ways.
A lot of times the best tool for the job is the one that works great for you.
People can easily adapt to different vehicles in a similar manner.
It is a fair criticism and some languages do fare better than others. Python is kind of in the middle there in my opinion. It's pretty easy to keep a relatively simple dependency graph with a little bit of discipline.
Little tweak here, little tweak there...
Another gigantic unspoken issue is that people have started building tons of stuff with React on purpose for some reason.
This is one of the worst things I have ever heard of proposal wise.
The worst. I can't even. Literally.