Why I Don't Ship Preferences

Woman holding head in confusion and frustration

Photo by Uday Mittal on Unsplash

Open ClipMan‘s settings. You’ll find six things: a history size chooser, a keyboard shortcut picker, a macOS permission checker, a menu-bar icon contrast enhancer, a toggle for launching at login and the update handler. That’s it. No themes, no appearance options, no “advanced” tab hiding twelve more toggles. The settings view occupies a single, un-tabbed pane.

All the apps in our catalogue are similarly minimal in their configuration options.

This isn’t laziness. It’s a design decision — one I’ve arrived at through experience rather than ideology, and one I want to explain because I think it’s more controversial than it sounds.

The preferences trap

Every preference is a question you’re asking the user to answer.

“Should the clipboard history retain formatting?” “Should the window float above full-screen apps?” “Should the keyboard shortcut use the left or right modifier key?” “Should the app show a menu bar icon or only appear in the Dock?” “Should copied passwords be automatically excluded?” “Should duplicate items be collapsed?”

Each question has a reasonable answer. Each answer will be different for different users. The natural conclusion is: make it configurable. Let the user decide.

Here’s the problem. Every preference you add:

A preference isn’t a feature. It’s a deferred decision — a place where the developer couldn’t or wouldn’t choose, so they pushed the choice to the user. Sometimes that’s the right call. Often, it’s not.

Opinions are features

The alternative to a preference is an opinion. Instead of asking “should the clipboard history retain formatting?”, you decide: yes, it should, because losing formatting is a worse default than keeping it. Users who want plain text can use the “paste and match style” shortcut, which is already a standard macOS convention.

Instead of asking “should the window float above full-screen apps?”, you decide: no, because full-screen mode is a deliberate choice to focus, and a floating window defeats that purpose. The pinned window is for normal desktop use.

Instead of asking “should duplicate items be collapsed?”, you decide: yes, because nobody benefits from seeing the same text four times in a row. The deduplication is silent. The user doesn’t need to know it’s happening, and they certainly don’t need a checkbox to disable it.

Each of these decisions eliminates a preference. But more importantly, each one eliminates a question. The user doesn’t have to think about formatting retention, or full-screen behaviour, or deduplication. They just use the app, and it does the right thing — where “the right thing” is whatever I decided was right, based on my understanding of how the tool should work.

This is opinionated software. The opinions are the product.

The one right default

Most preferences exist because the developer can imagine two reasonable behaviours and doesn’t want to pick one. But in practice, one of those behaviours is almost always better for almost all users, and the preference serves only the tiny minority who want the other option.

For ClipMan, my opinionated reasoning runs as follows:

Launch at login is a genuine preference — some people want their utilities running immediately, others want to launch them manually. There’s no universally correct answer. This gets a toggle.

“How many clipboard items to keep” is a preference where the right answer for almost everyone is “a lot.” I could have defaulted to 200 and not offered an option at all. The option exists because storage-conscious users on older machines might want to limit it, and because power users might want more. The range is narrow (10-500) and the default (100) is sensible. Most people will never touch it.

The keyboard shortcut is a genuine preference because shortcut conflicts are unpredictable — the right shortcut depends on what other apps the user runs. This has to be configurable.

Everything else about ClipMan is fixed. The polling interval (500ms). The deduplication behaviour. The paste simulation technique. The font in the browser. The animation speed. The pinning mechanism. The sort order. These are all things that could be preferences. None of them are, because I picked the right values (or at least defensible ones) and moved on.

The settings paradox

There’s a paradox in user-facing software: the more settings you offer, the less likely any individual setting is to be discovered, understood, and correctly configured. A settings view with thirty options is functionally equivalent to no settings at all, because the vast majority of users will never open it, and the ones who do will be overwhelmed.

The apps that succeed with complex settings — VS Code, Firefox, Blender — succeed because their users are technical, patient, and invested. They’ll spend an hour configuring their editor because they’ll spend thousands of hours using it. The return on investment is obvious.

A menu bar utility that prevents accidental quits does not warrant an hour of configuration. It warrants zero minutes of configuration. You install it. It works. The end.

This is the insight that drives the design: the amount of configuration a tool deserves is proportional to the amount of time the user spends actively interacting with it. A clipboard manager should be invisible. An invisible tool should not demand attention for its settings.

What I’ve removed

It’s worth mentioning a few preferences that existed briefly and were removed.

ClipMan originally had a “sound on copy” toggle — a subtle click sound when a new item was captured. I added it, used it for a day, and ripped it out. The sound was distracting. If the sound was distracting for me, it would be distracting for most people. A toggle to disable it would be an admission that the feature shouldn’t exist. So I removed the feature rather than hiding it behind a toggle.

ActiveSpace originally had a font size preference for the space number in the menu bar. I agonised over this because different users have different display scaling, and the “right” size depends on their setup. Then I measured the standard menu bar height, picked a font size that looked balanced, and tested it on two different display scales. It looked fine on both. Preference removed.

WindowPin originally had an opacity slider for the pinned window. This seemed like a reasonable preference — maybe you want the window slightly transparent so you can see what’s behind it. In testing, any opacity below about 85% made the content hard to read, and anything above 95% was indistinguishable from fully opaque. The useful range was so narrow that a slider was overkill. I set it to 100% and moved on.

Each of these was a case where I initially reached for a preference because I wasn’t sure what the right answer was, then figured out the right answer, and realised the preference was no longer needed.

The JorvikKit standard

JorvikKit — the shared component library that all the apps use — provides a standard settings view with four things: a keyboard shortcut recorder (from Sindre Sorhus’s excellent KeyboardShortcuts library), macOS permissions handler (where required), a launch-at-login toggle (via the SMAppService API), and an update check interval picker (never, daily, weekly).

That’s the baseline. An app can add its own settings alongside these, but in practice, most apps add at most one or two — a history size for ClipMan, a capture-rate and “pin to all spaces” for WindowPin, a “quit mode” selector for QuitProtect.

The consistency is the point. Every Jorvik utility has the same settings layout, the same keyboard shortcut mechanism, the same launch-at-login behaviour, and the same update checker. When you’ve used one, you’ve used them all. There’s nothing to learn. There’s nothing to configure. You set your shortcut, tick “launch at login” if you want it, and close the window.

When preferences are right

I don’t want to overstate the case. There are situations where preferences are the correct design:

Accessibility. Font size, colour contrast, reduced motion — these aren’t preferences, they’re accommodations. The user isn’t expressing an aesthetic opinion; they’re telling you what they need in order to use the software at all. Fortunately, macOS handles most of this at the system level, and SwiftUI apps inherit the user’s accessibility settings automatically. But if your app has custom rendering that doesn’t respond to system settings, you need your own controls.

Conflicting system resources. Keyboard shortcuts are the clearest example. There’s no shortcut that’s guaranteed to be available on every Mac, because every user has a different combination of apps, system shortcuts, and muscle memory. The shortcut has to be configurable.

Genuinely subjective choices. If there’s no objectively better option — like whether a window should appear on the left or right side of the screen — a preference is appropriate. But these are rarer than you’d think. Most “subjective” choices have an answer that’s better for the majority, and the preference serves only the minority who disagree.

Destructive or irreversible actions. “Are you sure you want to quit?” is QuitProtect’s entire purpose. The preference isn’t whether to intercept commandQ — the user installed the app specifically for that purpose — but how the user prefers to action the quit. This is a preference because only the user knows which method (double-tap or hold) works best for them.

The compound simplicity

Seventeen apps with two to four preferences each, versus one app with sixty preferences that does the same things. The compound simplicity of the former is something you feel rather than count.

When something goes wrong with ClipMan, I don’t ask “what are your settings?” There are only a handful and I know how they manifest. The state space is tiny. The bug, if there is one, is in the code — not in an unexpected combination of user-configured options.

When I want to add a new feature, I don’t have to decide whether it should be on by default, off by default, or behind a “labs” flag. I add it. If it’s good, it stays. If it’s not, I remove it. There’s no preference to maintain, no migration path for users who enabled it, no documentation to update.

And when a new user installs the app, they don’t have to configure anything. They press a keyboard shortcut and the clipboard history appears. That’s the experience. Not “first, open settings and configure your history size, paste mode, deduplication behaviour, sound feedback, and appearance theme.”

Install it. Use it. Forget it’s there. If I’ve done my job right, you’ll never open the settings at all.