Accept It: Software is Wabi-sabi

Last week, after dealing with a frustrating build and deployment issue, I reflected on what makes software development frustrating at times–specifically, the well-known feeling that code “rots” over time. I happened to glance at a small Zen rock garden my wife had given me long ago and was reminded of wabi-sabi.

Wabi-sabi is a Japanese worldview that accepts transience and imperfection. It is about accepting that the world around us is imperfect, impermanent, and incomplete. We experience wabi-sabi all around us–a small ding in an otherwise flawless car, a neglected barn collapsing on itself, a neighbor’s building project that is continuously ongoing. It gives me peace to accept that software suffers from these traits as well, but we have developed tools to make the situation better.

Software is Imperfect

It’s self-evident to anyone who has ever written a computer program or tried to manage a development project: No matter how hard you try, software has bugs. Some we know about, and some we don’t. Our goal at Atomic Object is to go about developing software in a way that minimizes the impact of the imperfections, and we employ several practices to ensure high quality:

  1. Test Driven Development (TDD): We write failing tests first, then implement features to get the tests to pass. This helps us prove the code is doing what we expect. It also helps catch regressions in the future. Easy testability is also a sign that code is thoughtfully architected (though not always).
  2. Pair programming: I always think of people’s skill sets as slices of Swiss cheese (holes representing gaps in knowledge). Hold any one slice up to the light, and you can see all the holes plainly. But if you put two different slices back to back, much less light gets through. It has been my experience that pairing results in higher quality code with less bugs and less risk of extensive refactoring.
  3. Continuous integration: Each time code is pushed to the remote repository, all tests are run. We catch regressions early and don’t allow a build with failing tests to make it into production.

Software is Impermanent

Traditionally, software impermanence manifests itself by the physical medium failing. As a kid on a 286-running DOS, I often dealt with floppy disks and hard drives becoming corrupt. Now that so much of software is stored on smarter, more redundant systems (better filesystems, backed up cloud architectures, etc.), failure of the physical medium is less of a problem. Instead, platform churn and updates are more often responsible for impermanence. In the last two weeks alone, I’ve come across this issue with both a mobile (iOS, Xcode and Swift language updates) and web app (developed on Drupal 6, no longer supported going forward).

We can’t solve impermanence, but we can improve things by being selective about the number of third-party integrations we bring into a project (the fewer the better), and using package management (npm, Carthage, gems, NuGet, etc.). If you have a software product and expect it to continue to be secure and development-ready, plan to spend time each year on maintenance to update software packages and port to new platform versions.

Software is Incomplete

Software products are rarely ever “done,” and most companies and entrepreneurs have more ideas than resources.

At Atomic, we work on client projects and commit to staying within a fixed budget and exercising scope control. We accept that software is never done and there will always be additional features that are nice to have, so it is very important that we build functionality with the highest value first. We accomplish this by ensuring we are always working to a well-defined, groomed backlog of stories that are prioritized by our clients. Our Delivery Leads are experts at keeping teams running efficiently and building the most valuable software for our clients.


It is easy to become focused on problems when developing software products. Engineers are especially susceptible to focusing on bugs, maintainability problems, and incompleteness. Accepting and being mindful that software products, like the natural world around us, are never perfect, permanent, or finished has given me some small sense of peace and helped me focus on how to make the situation better.