Removing a feature is a feature
Ultimately, your users use your product because they’re trying to solve a specific problem. It could be getting from point A to point B, finding their subsequent romantic interest, or having someplace to store their vacation photos. Whatever the reason, they have a specific task in mind, and your product is merely a means to an end. That means that every “nice to have” feature that doesn’t solve the problem they’re trying to solve isn’t just product cruft. It’s actively standing in their way.
Features aren’t free
Features come with a genuine cost to users. We had a motto at GitHub, part of the GitHub Zen, that “anything added dilutes everything else.” In reality, there is always a non-zero cost to adding that extra option. Most immediately, it’s time you spend building feature A instead of building feature B. Beyond that, it’s the cognitive burden you’ve just added to each user’s onboarding experience as they try to understand how to use the thing you’ve added (and if they should). In the long run, it’s much more than maintenance. Complexity begets complexity, meaning each edge case you account for today creates many more.
WordPress, the popular blogging platform famously has a similar philosophy, “decisions not options.” Every time you provide a user with an option, you’re asking them to make a decision, and those decisions quickly add up, especially when the user doesn’t care or doesn’t fully understand the implications. Ultimately, many of these decisions are technical or domain-specific decisions. As a project maintainer, as the subject-matter expert, you must absorb all that complexity on behalf of your users, not to kick the decision down the line.
With every new feature you add, users will need to go through that learning process all over again, not to mention that new knob you added for User B, because “why not? It’s just one knob” is going to make it harder for User A to find the knob they’re looking for.
There’s no such thing as declaring “feature bankruptcy.”
Even though we often call it “technical debt,” sadly, there’s no such thing as declaring “feature bankruptcy.” Every feature you add creates an implicit contract with your users that you will perpetually support that feature. That means that every dependency update, every redesign, and every refactor becomes exponentially more complex with each new feature, as you have an ever-increasing list of things you must now support. This technical debt quickly adds up to create a perpetual engineering tax on feature development in the form of ongoing maintenance and backward compatibility.
Product debt isn’t a foregone certainty. Chances are, users don’t need quite as many knobs as you think. Research suggests that 90% of users adjust fewer than 10% of settings, with the majority of users changing, at most, about 15% of configuration parameters for any given piece of software. That means that upwards of 80% of settings shouldn’t even be there in the first place. Rather than slowing marching your product’s settings page towards eventually resembling the complexity of a space shuttle cockpit, you should have the discipline to build features that support your ideal use case (and only your perfect use case).
Unfortunately, once a feature’s been added, once it’s in the hands of users, whenever you make a change, regardless of what the change is, a non-zero number of users are going to complain that the change broke their workflow. Thus, the easiest way to avoid upsetting users is often to prevent the feature from being added in the first place.
Playing feature goalie
Absent your intervention, projects tend to become feature Christmas trees, with each stakeholder adding their domain-specific ornaments. This happens for several easily avoidable reasons, at least if you can learn to spot them ahead of time:
-
Being reactive to ad hoc requests — customer feedback is invaluable, but your users are experts at using your product, not building it. A one-off feature request that might satisfy a single user might not be the right move for your product in the long run, especially if they’re not your ideal user. Avoid the temptation to play feature whack-a-mole. Instead, make your taste, vision, and foresight a feature in and of itself, building products that proactively solve your target users’ needs before they know they have them rather than reactively implementing a patchwork of individual features to satisfy your loudest users’ complaints.
-
Scope creep — projects naturally tend to drift towards solving problems beyond their original purpose. Once you’ve got the 0.1 that tackles one problem, it’s all too easy to start seeing related issues that could be tackled similarly, albeit less well. If your e-reader has an internet connection, you might as well add a monochrome web browser, right? When problems are similar but not the same, your product becomes sort of good at lots of things rather than being the best at the thing your users want to use it for. There’s also an opportunity cost to developing that other feature. Define the scope early on and purposefully revisit that discussion wholesale before agreeing to tackle any feature beyond your predefined problem space.
-
Scratching a technical itch — Technology can often make new user-centric functionality possible, but some of the highest impact features are also some of the most boring to implement technically. Borrowing another phrase from GitHub Zen, favor practicality over purity. Philosophically impure features that violate the canons of a computer science textbook may be the most useful to users and vice versa. Avoid the temptation to fixate on the shiny new thing just because it’s glossy or because it’d be a fun technical challenge to tackle, and focus on the most practical route to putting valuable features in the hands of your users as immediately as possible.
-
Not understanding your users’ needs — Who’s your target user? What problem are they trying to solve? How is your product uniquely positioned to solve it? It’s easy enough to look at what features you’re technically able to build or what features your competitors implement and match them point-for-point without regard for why you’re creating it. Unless your team has a shared understanding of your users’ unique needs, you’ll quickly change course from solving one problem well to not solving lots of issues at all.
-
Pushing complexity onto your users — Computering is hard, but that doesn’t mean your product has to be hard to use. When adding complexity to the user experience, pause to consider if there is a way — even if it requires additional effort on your part — to absorb that complexity on behalf of your users, especially if you can do it in a way that they don’t even realize you’ve intervened. If you’re better positioned to make an informed decision than your user, don’t add another setting. Just make the decision. If you can correct the user’s mistake without presenting an error message, silently correct it. Heck, leverage the user’s previous interactions to hide the feature entirely if you don’t think they’ll use it. Great features are complex to build but easy to use, not the other way around.
If you see yourself mimicking one of these feature development antipatterns, it may be time to play “feature goalie” a bit. That’s not to say you need to keep the proposed feature out of the product entirely, but it’s a good indication that you should give it a critical look and potentially scope things down to more directly support your target use case. Can you implement it without a toggle? Only expose it to power users? Bake it into the out-of-the-box experience as an intelligent default. If the feature doesn’t bring your target users joy, it’s probably best to cut it. Put another way, if the feature’s not part of the solution, it’s likely part of the problem.
Conclusion
Features aren’t what makes a product great. Being the best at solving a particular problem does. Every time you remove a feature that doesn’t support your product’s core use case, you’re adding an implicit feature that does. Every feature you add creates an implicit contract with your users that you will perpetually support that feature. That means that every dependency update, every redesign, and every refactor becomes exponentially more complex with each new feature. If the feature doesn’t bring your target users joy, it’s probably best to cut it. Put another way, if the feature’s not part of the solution, it’s likely part of the problem.
If you enjoyed this post, you might also enjoy:
- How to make a product great
- Why open source
- Twelve tips for growing communities around your open source project
- 15 rules for communicating at GitHub
- 19 reasons why technologists don't want to work at your government agency
- Five best practices in open source: external engagement
- Four characteristics of modern collaboration tools
- Twelve things a product manager does
- Speak like a human: 12 ways tech companies can write less-corporate blog posts
- Why everything should have a URL
- Optimizing for power users and edge cases is the easy part
Ben Balter is the Director of Hubber Enablement within the Office of the COO at GitHub, the world’s largest software development platform, ensuring all Hubbers can do their best (remote) work. Previously, he served as the Director of Technical Business Operations, and as Chief of Staff for Security, he managed the office of the Chief Security Officer, improving overall business effectiveness of the Security organization through portfolio management, strategy, planning, culture, and values. As a Staff Technical Program manager for Enterprise and Compliance, Ben managed GitHub’s on-premises and SaaS enterprise offerings, and as the Senior Product Manager overseeing the platform’s Trust and Safety efforts, Ben shipped more than 500 features in support of community management, privacy, compliance, content moderation, product security, platform health, and open source workflows to ensure the GitHub community and platform remained safe, secure, and welcoming for all software developers. Before joining GitHub’s Product team, Ben served as GitHub’s Government Evangelist, leading the efforts to encourage more than 2,000 government organizations across 75 countries to adopt open source philosophies for code, data, and policy development. More about the author →
This page is open source. Please help improve it.
Edit