Over the weekend, I saw a hot take on Mastodon that went something like this:
If you think CSS is some sort of “problem” that you need to solve with frameworks, maybe you just don’t know how to use it.
I see this attitude a lot, and it’s not just limited to CSS: the idea that needing a framework to solve your problem is some sort of failing. That if you don’t fully understand the problem space in which you’re working, you’re doing something wrong.
The issue with this line of thinking isn’t that it’s incorrect. Because, unabashedly, yes: frameworks exist to help people who don’t know how to use lower-level technologies. That is not a bad thing! The entire point of a tool is to transform what we can to do into what we want to do.1
No, the issue with this line of thinking is that it’s toxic. It’s gatekeeping. It points and laughs at people who — for whatever reason — need a tool to solve their problem. Oh, you use a framework to do that? Sounds like a skill issue.
But here’s the thing: when we’re working with something unfamiliar, we all have skill issues.
From time to time, I think about this blog post by James Hague called Write Code Like You Just Learned How to Program Write Code Like You Just Learned How to Program prog21.dadgum.com/87.html . He writes about an “Intro to BASIC” class he took in high school. Already knowing how to program, he completed an assignment by banging out a quick algorithmic demo that drew some colored lines on the display. He was blown away, though, by another student who made an animation with “crazy stuff, like a skull that dripped blood from its eye into a rising pool at the bottom of the screen”.
The kicker was that the other student had no prior programming experience. He wrote what most of us would consider Bad Code — manually setting timers, no loops, no variables. He kept track of everything by hand on a piece of graph paper.
Here’s the quote that sticks with me:
My prior experience hurt me in this case. I was thinking about the program, and how I could write something that was concise and clean. The guy who wrote the skull demo wasn’t worried about any of that. He didn’t care about what the program looked like or how maintainable it was. He just wanted a way to present his vision.
Even though James’ classmate had a “skill issue”, he didn’t let it stop him. He took the tools he knew, and he used them to realize his idea as best he could. That’s amazing! We should be celebrating that whenever it happens!
It is, of course, possible to present your vision with clean, maintainable code. But the point is that the code is secondary. The vision is paramount.2
At this point, people start to protest that there can be consequences to building things you don’t understand. And they’re right! Accessibility issues can lead to unintentional discrimination. Infrastructure issues can lead to data loss. Security issues can actually put people in danger.
Programming is at the awkward intersection of a few different disciplines. It’s a form of engineering, a form of math and a form of artistic expression. And as with any other art form, people who have creative visions will want to express them before they’re experts in the medium. Repeatedly creating things (aka practicing) is how people develop that expertise. The first step to being good at something is to be bad at it!
Furthermore, working with technology means dealing with a metric ton of problem spaces. Let’s say you have an idea for a small social web app. Here’s a partial list of technologies you’ll need to figure out:
- HTML: How do I represent the content that the user sees and interacts with?
- CSS: How do I make it look the way I want it to?
- Ruby/Python/PHP/etc: How do I actually write the “logic” of this thing?
- SQL: How do I store and retrieve data?
- HTTP: How does a webpage communicate with the server?
- DNS: How do I associate a domain name my app?
There are also problems that cut across technologies:
- Deployment: How do I make my code run publicly?
- Accessibility: How do I make sure my app is inclusive of disabled and neurodiverse users?
- Authentication: How do I know that a user is actually who they say they are?
- Authorization: How do I ensure that users can only access what they’re supposed to?
Not to mention the various sub-issues: browser quirks, XSS, form submission, SEO, SQL injection… way more than I could practically list here. The point is that it is not feasible for one person to have deep knowledge in all of these areas. How many people do you know who are experts at responsive CSS and tuning the Ruby garbage collector and managing a Postgres cluster and screen reader testing?3
Just as with cryptography, there is no shame in using these abstractions. If you can’t figure out how to provision servers, use a cloud provider. If you’re not sure how to handle HTTP requests, use a backend framework. If you’re spinning your wheels on SQL, use an ORM. If you’re getting stumped by specificity or the cascade — as much as I dislike like it Tailwind is a Leaky Abstraction | jakelazaroff.com Although Tailwind does have some benefits, ultimately it’s just one more thing to learn. jakelazaroff.com/words/tailwind-is-a-leaky-abstraction/ ! — use Tailwind.
One common objection here is that since all abstractions leak, relying on ones you don’t understand trades short term convenience for long term pain. That argument carries the implicit assumption that it’s better to optimize for the future than for the present. But short term convenience can be the difference between a project existing at all and being abandoned unfinished.
Bret Victor speaks to this in his seminal talk Inventing on Principle Bret Victor - Inventing on Principle www.youtube.com/watch?v=PUv66718DII&t=573s :
Ideas are very important to me. And the thing about ideas is that ideas start small. Ideas start out tiny and weak and fragile. In order to develop and mature, ideas need an environment where the creator can nurture them. Kind of take care of them, feed them and shape their growth. And to me, that’s what the principle of immediate connection is all about.
Although developer tools mostly don’t have the sort of immediate connection Bret is talking about, the larger point remains: obstacles in a creator’s way can kill ideas. When we try to shame people into becoming experts before building, we end up shaming them into giving up before their ideas are realized.
The world is poorer when friable foundations lead to crumbling creations. But it is poorer still when we are so concerned with the foundations that we never create at all.
This quote is lightly paraphrased from Bret Victor’s wonderful essay A Brief Rant on the Future of Interaction Design A Brief Rant on the Future of Interaction Design worrydream.com/ABriefRantOnTheFutureOfInteractionDesign/ . ↩
This is the tension between Tribe 3 and Tribes 1 and 2 that Joseph Gentle alludes to in 3 Tribes of Programming 3 tribes of programming There's an old joke that computer science is a lie, because its not really about computers, and its not really a science. Funny joke. Everyone laughs, then someone says "Yeah but it sort of is about computers though, isn't it?". Feet shuffle awkwardly. Someone clears their throat and before you josephg.com/blog/3-tribes/ . ↩
That’s why people work in teams: it’s the only way to ensure expertise in all these areas. If you’re a business or a public service, you should absolutely spend the money to make sure you’re not introducing any issues due to lack of experience. Criticizing corporations for cutting corners is fair game. ↩