Programming Bowls
Realizing how much of the programming space is just bowls
One of my favorite videos I watched recently was by Pewdiepie, and while the title is “help, Im going through a midlife crisis…”, you realize about 3/4 of the way through that it was just bait. The real topic of the video is minimalism, and a great story about the philosopher Diogenes and his bowl. Diogenes was known for only having a single possession to his name: a wooden bowl. One day as he was walking he saw a child by the river drinking the water by cupping his hands together. It was in this moment Diogenes realized that his bowl was useless since he had his hands, and he threw away his bowl. It was the ultimate commitment to the principles he believed, that true happiness was not found in wealth or possessions. You should watch the video because 1. Pewdiepie tells the story way better than I do and with a lot more humor, and 2. he articulates how he’s carried out the principles of minimalism in his own life and living by principle.
I’m not going to argue the points of Diogenes in the grander scheme of life, however I will explore what this might look like in the world of programming. For a few months now I’ve been reconsidering how I approach and solve problems in software, especially in web development. I now am starting to ask myself “what are the bowls of programming?”, and in this post we’ll consider a few.
Before we get started, I want to make it explicitly clear that these points are not absolute. This way of thinking should be seen as a spectrum, and depending on the context of what you’re building or solving, you may land on different levels of programming minimalism. What I would encourage is to dig deep and ask yourself with honesty where your solutions should land, knowing that sometimes it’s ok just to choose whatever you feel most comfortable in. It’s your life; do what you want, but I hope to argue a point of responsibility towards other programmers.
Unnecessary Complexity
While this point mostly applies to web development, it can apply elsewhere. For the sake of illustration we’ll look at the web dev space thanks to Javascript frameworks. As web apps started to take off and more and more people moved towards Javascript, there was a brief period where we were onto something. JAMStack, aka “Javascript, APIs, Markdown” was a simple yet brilliant way to standardize building apps or websites. This was the golden era of static site generators and simple client-server relationships, where if a hosting platform didn’t work out it was simple to move somewhere else. The frameworks that emerged were platform agnostic, people hosted their own stuff, and it created an open web.
Years later we start to see complex SSR Javascript frameworks being pushed more and more by hosting providers. Next.js brings a new developer experience that a lot of people latch onto and quickly becomes one of the most commonly used frameworks in the ecosystem. The main problem is that it has become too complex and specially designed to work on Vercel. Yes you can “self host” Next.js, but it won’t work or perform the same way it does on Vercel. A whole initiative was started by Netlify and Cloudflare to create a fork called OpenNext to help make self hosting a fully featured Next.js app possible, and it’s still not meeting all the features Next.js offers.
Perhaps the most frustrating part is that most developers don’t actually need Next.js 95% of the time when building web applications. We’ve even seen influencers give tips on how they can speed up their Next.js app by making all pages render as static except for API routes. It’s simply bad education for new developers who have no idea how simple it can be to spin up a backend API and use that in combination with a static app. Some don’t even know the difference between client and server architecture, and that’s ok because we were all there once, but I don’t want people to stay there. It’s one of the reasons I built bhvr as I wanted people to know that you can have a solid DX while not risking platform lock-in. It can’t be used for every problem, and even I am willing to admit that an SSR stack like Next.js or TanStack Start is better suited for an ecommerce platform. What I am saying is people should know the options out there. You don’t need the complexity of an SSR stack.
Next.js, by and large, is a bowl.
Dependencies
Another piece of the programming pie that could be argued as a bowl is dependencies. Just recently we’ve seen multiple supply chain attacks on NPM and even a worm. We simply run install
with trusting ignorance that all the code we’re downloading is benevolent. The majority of it is, but it’s the reality that most of us don’t care that’s more disturbing. We’ve become lazy and would rather install a package that’s less than 100 lines of code rather than implement it ourselves and know for a fact that it’s not going to attack us. Dependencies also make us deal with clashing version interdependencies, where two packages require the same external package and they both require different versions. It’s an awful experience.
While all of these things are true, we must admit the necessity of package managers and dependencies in modern software. Not everything can be written from scratch, some packages like cryptographic libraries need audits and should not be rolled by hand. There are always exceptions and we have to look at it with nuance. With that said, all of these things have made me stop and think, “do I really need to download this?” or “what am I downloading exactly?” For some apps we’re totally ok just installing twenty dependencies as it’s not a serious project, but what about the software we want to last longer than a year? What about web apps that people depend on and we want to keep them running five or even ten years from now? We should think about these things before we just run install
.
Dependencies, in many cases, are a bowl.
Languages and Development Environments
If I haven’t lost you yet then I’m probably about to with this last one. We’re getting into pretty deep water and areas that most (including myself) are not ready to tread. There are some who argue and live by the principle that most programming languages or development environments are bowls. A huge influence into this particular mindset is 100 Rabbits, and one of my favorite blog posts on the subject is Weathering Software Winter. In the post they discuss how their desire to live on a solar-powered sailboat greatly limited the kind of software they could download or build with, especially as designers. If you’ve ever touched an Adobe product you probably know exactly what they’re talking about; the need to constantly be connected to the internet to use a piece of software. Even when exploring building their own, they found limitations around tools like Xcode that constantly required heavy downloads or other languages that needed to install a bunch of packages. It’s these situations of limited network speed that we don’t think of often, and it’s exactly where 100 Rabbits found themselves.
The solution? Perhaps a bit extreme, but they built their own VM and assembler. With a VM they could compile software to run on almost any device, no matter how old it is or what the OS is. It’s low level enough to accomplish most tasks, and it’s with this combination that they continue to build basic OS level applications to fulfill their design and everyday needs. Their goals were to have something so simple that they could fit the documentation on a t-shirt and reimplement it within a weekend. When you know your software so well that you also have a good idea of what it looks like in assembly, you can truly maintain and repair your tools. These tools are also built to last, using recycled hardware that is normally thrown out. A form of eco-minded software development that has labeled itself as permacomputing. Now of course this is not something we can all just pick up and start rewriting all software. The world is complex which means we have complex software running everywhere, but it also demonstrates that it doesn’t always have to be that way. There are ways we can build thoughtful, long lasting, and meaningful software to meet our own needs.
For 100 Rabbits, most languages were a bowl.
Where Do We Land & Why Bother?
No matter how hard I might argue these principles, I hope my point of nuance comes across. None of these are absolutes. One could argue programming minimalism to the point of writing ones and zeros. The range of how far you can go with throwing out programming bowls depends on what you’re building. 100 Rabbits also pushes for more offline applications and depending less on the connected web. However there is a big difference between building simple desktop apps and an app like ICEBlock. Context decides how complex something needs to be. We don’t want to roll our own cryptography; it’s ok to trust libraries that have been audited and battle tested.
A point that Pewdiepie makes in his video is that while he has thrown out a lot of the stuff that he doesn’t need, it doesn’t mean he throws out everything. There are plenty of things he owns simply because he enjoys them, like a random action figure. If it’s something that brings happiness then that’s great! I have a small rock that looks like an owl on my desk. It doesn’t do anything or serve any purpose; I just like it. I believe the same can go for software engineering. Sometimes I like how quickly I can spin up an app with Bun and Typescript. That’s actually what I did this weekend while drafting this post. If I really wanted to I could have used React to handle the client side logic, but I personally thought the app was simple enough that I didn’t need it. Again, if I wanted it, that would have been ok too. There are no absolutes in the decisions you make in programming as far as I’m concerned.
If that’s the case, why bother? There is one important factor that we cannot forget as we make these decisions: people. My greatest aspiration in programming is to build software that advances principles such as privacy, security, freedom, and the ability to repair. ICEBlock was an iOS app that was taken off the Apple App Store, and that is a chilling reminder that the stack decisions we make actually do matter. Yes a web app could also be taken down but it’s much harder to do. I could have used React in my simple code sharing tool but by choosing to use just html, css, js, and sqlite, it’s a lot easier for someone to use and alter long term without any potential dependency issues. We also have to consider if what we’re building is going to be used by other developers and in what ways. A great example is @noble/hashes where there is zero dependencies but acts as a foundational building block for cryptographic operations.
In the end it comes down to how much we care. Not speed for the sake of speed, or minimalism for the sake of minimalism, but for privacy, security, freedom, and longevity for the sake of people who depend on it.
Keep the bowl or throw it out, but at the very least think about it first.