Have you worked on a larger project? Maybe something that required you to work in more than one code base or more than one package? Then you might have already encountered situations in which you needed to take a problem apart into pieces. This is by no means an easy task. And that is what makes it interesting. 😄
I'm going to assume that when you're faced with a problem you're going to split it into smaller chunks. There are lots of ways how to do this 1. While there are no wrong decisions, some might be better than the others. Because we're not solely taking a problem apart, we're looking for ways how to deliver value faster and reduce risk.
In a nutshell, this article is about Lean development. I believe you should always do as much as needed and as little as possible to get the current task done. By doing this you decrease the time-to-value for your users. When you do more you're placing bets on whether your current assumptions are right. Sometimes these bets will play out and sometimes they won't. The trick is to be aware of the risks you're taking.
Especially when you're creating something new and you want to test out ideas you need to make sure that you're not wasting time on the non-essential parts.
Deliver value faster
I believe that we all create software to make other people happier or more productive. Maybe our software lets people create things faster or helps them avoid certain mistakes. However, sometimes developers believe that solely a 100% complete feature accomplishes this job. Otherwise, your customer might hit that edge case the developer knows of and this is not acceptable 2. At the same time, you might have heard about the Pareto principle. According to it, you're going to build 80% of a feature in 20% of the time. Vice versa this means that 80% of your time is required to build the last 20% of the feature.
I got a couple of questions for you.
- Is the real customer value in the last 20%
- If yes: Why didn't you start with them?
- If no: Why let the customer wait?
Ask yourself "Why would I let my customer wait 80% of the time if the good part of a feature is already done?" I'm pretty certain that the first 80% include useful functionality. If we release these features once they are ready we can help our customers faster.
Identify wrong assumptions earlier
Once you are able to deliver value faster you'll also shorten the feedback loop. Even better, since the changes you're going to roll out will be smaller you can also get more focused feedback. That's great.
Imagine you're building a design system. You'll probably start by defining the colors and some basic rules for typography. After you've done this, would you place a bet that these definitions will not change while you build the rest? Are you also sure that they don't already conflict with what people have done so far (i.e. while the design system was not around)? I would claim that the safe way would be to take solely these changes and roll them out. You'll probably get a lot of feedback and find some issues. Fixing them now shouldn't be that hard since there is nothing else in the design system yet. If you would have built buttons, form components, etc. and only rolled out the design system once it was "done" this situation might be different.
The worst thing that can happen to you isn't that you need to fix a lot of components. It would be that people reject the design system completely because they can't fit it into their daily job. This would mean all of the time and effort you've put into creating the design system is wasted.
By making sure we're rolling out changes constantly and in small batches, we can keep our bets small. This reduces the risks we're taking at a time. The smaller the risks the higher the chances that everything will play out in the end3.
When we deliver faster and verify our assumptions early on we're making sure that we're not wasting time. Neither ours nor the time of our customers. In order for this to work, it must be OK to acknowledge that we don't know everything. That is fine. Nobody does. Even if they claim they do. Yes, I'm looking at you HiPPO.
Should you speak with your customer whenever you're unsure about something? Maybe. Personally, if the impact of the decision is large and hard to reverse then go ahead and talk to them. If the impact is small though and the decision can be easily reverted then it might also be fine to just go with a gut feeling. The important part is to know when to do what and to also document that somewhere. Because our time is also valuable and we should spend it with the efforts that are likely to create the most value.
How this relates to your MVP
An MVP or minimum viable product is something you built to, for instance, test a hypothesis. The hypothesis can be about a feature, user behavior, or anything else really. The important part is that you want to spend as little time as possible to figure out whether your hypothesis is correct or incorrect.
I'd like to add that you also don't want to build them in a way that they are in your way when you decide to move forward. Why do I say that? Because I often hear people describe them as prototypes. However, I think you should throw away a prototype after you've used it to figure something out. MVPs, on the other hand, are a starting point that you want to eventually grow into something bigger. That's why I would even call it harmful to treat them as if they were prototypes.
Let's have a look at the image above. It describes two different ways to slice a larger feature into an MVP (the colored parts are what will be included in the MVP).
Option A doesn't look too bad. Build some of the foundation (because we said we're not going to throw away the MVP) and add some features on top of that. To get to the finish line faster we're not going to include delighters4 though. If you decide to take this approach I'm generally on your side. But do we really need to build that much of the foundation now? Sometimes developers creep more features into the foundation because we said that we're not going to throw it away. Yes, but only if we figure out it makes sense. If the result of our experiment is that no one wants that feature, we're still going to remove it. So by creating a foundation for a possible future we're hoping that all our assumptions won't change. Even worse, once we've built it we might fall victim to confirmation bias and only accept the feedback that lets us keep it.
Update 2020-11-25: I've just rediscovered this picture which brilliantly shows a bad MVP. Functionality is all there but would you use it?
When you focus mostly on the foundation and not on the user and how you might even delight them what are your really validating here? I've seen a lot of MVPs that have been built like this. Users like to reject them because the features they offer are oftentimes worse than what is already there. I would argue that's due to the fact that there was little work on the things that matter to the users and a lot of work on the things that matter to the developer. The developers used the MVP mostly to validate some technical aspects. And when they ran out of time, they shipped what they had and the user wasn't happy. If you work like this I'd say you're setting yourself up for failure.
By now you might have guessed what is different about option B. Here, we're looking at one use case end-to-end. We're going to do what is necessary to make sure the foundation for the feature is good. However, we're not going to make assumptions about the next feature just now. Then, we're going to use the time we just saved and use it to build something that highlights the extra value this feature is supposed to create. By doing this we're making sure that the value proposition reaches our users. Now we can truly validate whether we're on the correct path or not.
Creating the right slice of a new feature to test an assumption might be the most difficult skill I have yet to master. In the end, everyone wants to do the right thing but sometimes these intentions conflict with each other. Navigating these conflicts without hurting people's feelings can be extremely difficult.
How do you tackle this kind of task? Do you agree that releasing small and often is the right approach? As always, I'm keen to hear other opinions. Reach out to @philgiese on Twitter.
If you're working with user stories, you might find this article helpful. ↩
My rule of thumb is to not argue out of an edge case. If you do, then this can easily lead to a situation where you spend most of your time on the parts that people will most likely not encounter. This takes away precious time from the features you should actually be focusing on. ↩
If your risks are low and the chances increase that you're building the right thing then this sometimes also means that planning becomes easier. Since you're not doing a lot of rework as you keep your batches small you might be able to make better estimates. However, you've never heard me say this. ↩
Delighters are features that, strictly speaking, are not necessary but add that little extra that gets your feature from being good to great. For instance, my car has small lights in its rear mirrors that project the logo onto the street when I open the door. Does this add value? No. Do I love it and show it to everyone whether they want to see it or not? Absolutely! ↩