Sai Chandrasekharan

· 4 min read

The Beauty of Software That Does One Thing Well

I’ve always had a soft spot for small, focused apps that solve one problem really well. Not everything needs to be a platform or have a hundred features. Sometimes, an app that fixes one annoying thing in your daily workflow is all you need.

A few apps I use every day come to mind.

Take Shottr, for example. macOS has a perfectly good screenshot tool built in. You take a screenshot, a thumbnail appears in the corner, and you can drag it into another app. The problem is that the thumbnail disappears after a few seconds. I can’t tell you how many times I’ve taken a screenshot, switched to another window to finish something, and come back only to find that it’s gone. Now I have to find the screenshot on my desktop or take another one.

Shottr fixes this. The screenshot stays around until I’m done with it. That’s literally the reason I started using it. It also has excellent annotation tools, scrolling screenshots, OCR, and a bunch of other features, but keeping that screenshot available is what won me over.

Another one is HazeOver. I tend to have a lot of windows open, especially when I’m working. Terminals, browsers, documents, Slack, and whatever else I’m switching between. HazeOver simply dims the windows that aren’t active. That’s it. The window I’m working on stands out, and everything else fades into the background.

I don’t have to organize windows or turn anything on and off. It just works. Such a simple idea, and it makes a surprisingly big difference.

Then there’s Amphetamine. Sometimes I want my Mac to stay awake, especially when I’m running something that takes a while. I could go into System Settings, change the sleep settings, and remember to change them back later. Or I could just click the Amphetamine icon in the menu bar and tell my Mac to stay awake.

All three apps do more than what I’ve described, but I don’t particularly care about most of those features. I use them because each solves a specific problem without getting in my way.

I think there’s something to learn from apps like these, especially as engineers.

We have a tendency to overengineer things. Someone comes up with an idea, and before we’ve even built the first version, we’re already thinking about all the things it could eventually do. What if we need to support multiple platforms? What if users want customization? Should we build a plugin system? What about extensibility? What happens when we have a million users?

These are all reasonable questions at some point. But do we really need to answer them before we’ve even figured out whether the original idea is useful?

I’ve seen this happen enough times over the years. A relatively simple problem turns into a much larger engineering effort because we start accounting for every possible future requirement. We build abstractions for things that don’t exist yet, add configuration options nobody has asked for, and spend time making the system flexible enough to handle scenarios we might never encounter.

And I get it. As engineers, we enjoy solving these problems. There’s something satisfying about designing a system that can handle everything we throw at it. But just because we can build something doesn’t mean we should.

My preference has always been to start simple. Find the one problem you’re trying to solve and fix that first. Don’t try to solve ten problems when you haven’t even solved the first one.

That doesn’t mean writing throwaway code or ignoring good engineering practices. You can build something simple and still make it reliable, maintainable, and well designed. And if the product takes off and needs more capabilities, you can evolve the architecture to support them.

I’d much rather deal with a real scaling problem when I have one than spend months preparing for a hypothetical one.

The same thinking applies to product features. Every new feature comes with a cost, even if it seems small. More code to maintain, more things to test, more potential bugs, and often more complexity for the person using the product.

It’s easy to justify adding features. Someone asks for something, it sounds useful, and we add it. Do that enough times, and eventually the product becomes harder to use than it needs to be.

I don’t think the goal should be to build software with the fewest features. That’s taking simplicity too far. The goal should be to make the things people actually want to do as easy as possible.

Shottr is a good example of this. It has grown into a pretty capable screenshot utility, but I can still take a screenshot and drag it somewhere without thinking about anything else. The additional functionality doesn’t get in the way of why I use it.

That’s the kind of simplicity I appreciate. The complexity can exist underneath, but it shouldn’t be something I have to deal with every time I open the app.

I also think we sometimes underestimate how valuable these small improvements can be. Saving a few seconds on something you do once a month probably doesn’t matter much. But removing an annoying step from something you do twenty times a day? That adds up. More importantly, it removes an interruption from whatever you were actually trying to accomplish.

And that’s really what I like about these apps. They don’t ask me to change how I work. They just make something I already do a little easier.

After spending years working on software, I’ve come to appreciate that more and more. It’s tempting to measure a product by how much it can do, but I think how easily it lets someone do what they came for matters just as much.

If I were starting something new, I’d rather begin with one problem, solve it really well, and see where it goes. There’s plenty of time to add features, build abstractions, and invest in more sophisticated engineering once there’s a real need for it.

Not every idea needs to become something bigger. Sometimes fixing that one annoying thing is enough.