A few months ago, CodePen co-founders Chris Coyier and Alex Vazquez spent an hour reflecting on the top 10 lessons they've learned over the last decade of work at CodePen. The entire episode is value-packed; but, the one lesson that has haunted me is 6: One thing at a time (jump to track). And, I just wanted to take a moment and amplify their message.
The whole point of running a company is to solve problems. As Alex teases in the episode, if they weren't solving any problems, they'd be out of business. But, when it comes to solving problems, Alex stresses that only one new problem should be solved at a time.
The example he gives in the episode is "learning Golang". Understanding how to use Golang was a new problem for the company. As such, in order to start integrating Golang into their work, they applied it in the context of an already-solved problem: sending emails. This way, Golang was the "one thing" they were solving—the email-sending logic already existed in Ruby; and, they just had to port it over to a new application server.
This lesson hits me hard in the feels because when I reflect on my own work history, some of the biggest mistakes that I've made in my career revolve around trying to solve multiple problems at the same time. Perhaps one of the most embarrassing examples of this is when I attempting to learn OOP (Object Oriented Programming) on a new project. This was two problems: I had to build a new application; and, I tried to do it in a new programming paradigm.
Needless to say, the project ended up coming in months late and was a horrible mess of hard-to-maintain code. Trying to solve two problems at the same time ended in disaster.
If It Can't Be Done Incrementally, Don't Do It
If I could be so bold as to add a corollary to the rule of "one new problem at a time", I'd suggest that if it can't be done incrementally, don't do it. Over the last 6-years, feature flags have revolutionized the way that I work. And, a majority-stake in that change is the fact that everything I do is now built and integrated incrementally. Until you've worked this way, it's hard to even articulate why this is so powerful. But, I literally can't imagine building anything of any significance without an incremental path forward.
When you build and integrate code incrementally as a rule, you are forced to think about the work differently. You have to break it up into smaller problems. And, the order in which those problems are solved (and integrated) starts to matters. This, in turn, allows you - and your external stakeholders - to create a better sense of how long things will take, how often value will be added, how far the project is progressing, and how the path forward (and expectations regarding delivery) might need to be adjusted.
This is another example of the power of constraints. When we apply constraints - either implicitly or artificially - to our work, we are forced to think more deeply and more creatively. And this ultimately leads to better outcomes.