Choices are Bad: The Anti-Settings Principle

Thursday, July 30, 2020
By dreeves

Bee holding a 'no settings' sign

What’s the most absurdly provocative way I can put this? Never imagine what your users will want! Apps must only ever do one single thing! If-statements considered harmful!

Yes, this is all pretty rich coming from the people who built a goal-tracking app with, if I’m doing this math right, multiplying out all the various settings… 73,728 types of goals. Not to mention all our reminder settings, pledge settings, ways to schedule breaks, settings for what happens when you derail, weaselproofing, etc etc etc. We’ve learned this the hard way, ok? Also we’re exaggerating. Some settings are great. And Beeminder is a big beautiful bounteous beast that can do amazing things that we, the creators, have never thought of [1] and that’s wonderful and we’re very proud. But there are some important rules of thumb that are counter to a lot of people’s — especially programmers’, especially our own — instincts. So listen up!

I know it’s exciting to imagine far-flung use cases and to try to please as many people as possible but it’s like Abraham Lincoln says: You can’t please/fool all of them all the time. If you’re very sure you’ve identified genuinely divergent use cases (and that you genuinely want to support both use cases, which as a startup you probably don’t!) then maybe it’s ok to add the setting. [2] My rule of thumb — and this is a necessary but not sufficient condition — is to wait for a user to make an impassioned argument for their use case. Never add a setting speculatively, i.e., by imagining what a user could want. Default to total paternalism where you decide what the user wants.

Or look at it from a programming perspective. As you add more settings you increase the number of possible code paths and places for bugs to hide exponentially.

Literally exponentially! It’s 2020 and we’re all clear on what exponential means, right? Say your app has a few simple checkboxes as settings and your code needs to work for every combination of them. Then you add one more measly checkbox. You’ve just doubled the number of combinations. I mean, not always. Maybe your app is pristinely designed and your settings are beautifully orthogonal. But probably not.

When debating a design choice, never say “let’s make it a setting!”

Need more reasons? We have a whole smörgåsbord for you to choose from! Documentation is much, much easier the fewer settings there are. Customer support even more so. And if you add a setting that turns out to be stupid, someone will get attached to it and it will be a big ordeal to get rid of it. Worst of all, it’s all too easy to add a setting due to uncertainty about what the right design choice is.

“I guess we can ship that as long as we include a setting to opt out of it” should be a glaring red flag. We’ve violated this a lot and I suspect we were always dead wrong to do so. An especially painful example was when we shipped a now-defining feature of Beeminder that both doubled our revenue and made Beeminder drastically more effective for users. We called it precommit-to-recommit at the time. Now we don’t call it anything because there’s no such thing as anything but precommit-to-recommit. But that’s my point. At the time we were too timid to ship that — goals that automatically continue and recommit you when you derail — without a setting to opt out of it. Which was a massive thorn in our side and source of complexity, user consternation [3], and technical debt for years.

Here’s one more reason to eschew settings: they’re a burden on users. In “Chapter 3: Choices” of Joel Spolsky’s User Interface Design For Programmers he argues hilariously against adding settings for most things, focusing on how baffling or obtrusive excess customizability can be. In a similar vein, see Basecamp’s exhortation to “Make Opinionated Software”. Your app should not be flexible and agnostic. It should take sides and have a cohesive vision.

Anti-Settings and Anti-Magic

If we wanted to get fancy or philosophical we could say that the Anti-Settings Principle and the Anti-Magic Principle are special cases of a more general principle: “try not to let the business logic branch”. Of course, most of the time there’s no choice (about there being choices). That’s just what the business logic is. If X then do Y else do Z, etc etc. But, just… resist it. Ask yourself if the business logic inherently must bifurcate or if, at least for the initial implementation, you can take just one of the paths. When you come to a fork in the road, do not take it. Pick a single tine. Bifurcation will bite you. This also relates to software engineering concepts like premature optimization being the root of all evil, and YAGNI.

Don’t Take Our Word For It

I think this is all becoming very conventional wisdom despite how hard-won it’s been for us. The huge open source encrypted messaging service, Signal, sums up the Anti-Settings Principle nicely as item number one of their development ideology: “The answer is not more options. If you feel compelled to add a preference that’s exposed to the user, it’s very possible you’ve made a wrong turn somewhere.”


 

Footnotes

[1] If we include our COO/CFO, Mary Renaud, then, ok, yes, we’ve thought of and probably tried every conceivable thing that can be done with Beeminder, including surely all 73,728 combinations of goal settings. Mary knows Beeminder better than anyone, including Bee and me.

[2] The idea that you shouldn’t add a setting without knowing for certain that there are users who need it can be taken to an extreme. Since I love extremes I’ve totally taken it there. The Shirk & Turk Principle says that you shouldn’t write any code at all until after you already have users using the thing you haven’t built yet.

[3] The very existence of that setting (to automatically quit your goal when you derailed) made it seem all shady that the default was to not automatically quit. Nowadays exactly zero [4] people are bothered that committing to your goal means committing until you explicitly end it. It’s so fundamental to how Beeminder works that it doesn’t occur to anyone to object. Quite the opposite: users routinely assume Beeminder is far harsher than it actually is. “You can quit or make the goal easier at any time, with one-week notice” is more generous than people at first expect. “You never have to catch back up after derailing because the graph resets from where you went off track” — likewise. People commonly assume that they’ll be penalized every day until they catch up to the original commitment. “And also if you ever go off track for a single day everything comes to a screeching halt until you explicitly opt back in” would nowadays sound ridiculous. As it should. But that sure wasn’t the case when that was a setting!

[4] Support Czar Nicky read a draft of this and corrected me: This expectation has been spotted a couple times in the wild. It’s kind of the exception that proves the rule though. We suspect that they came across some ancient video or post from before the precommit-to-recommit New World Order.


 

Image credit: Faire Soule-Reeves

Tags: , , , , , ,