« Back

Most programming is just user interfaces.

By that, I don’t just mean that GUIs tend to be more code than any other part of an application, although that’s probably true as well. Instead, I mean that most individual tasks involved in programming are a form of UI development.

We tend to think of the UI as a separate, and relatively unimportant, part of a program. There’s a core part, which solves a problem, and there’s a peripheral part, which exposes it to the user. We even use this language in systems when talking about the “kernel” vs the “shell.”

But there’s one problem with this way of thinking. Most programs don’t actually solve any problems. They just make it easier to access solutions that already exist.

For example, there’s an infamous post on Hacker News in which a commenter responds to the announcement of Dropbox by questioning it’s usefulness when compared with

“getting an FTP account, mounting it locally with curlftpfs, and then using SVN or CVS on the mounted filesystem”

And this person was not wrong! Dropbox didn’t solve the problem of accessing files from different devices; that existed already. It just exposed an existing functionality in a more convenient package. That’s what UI is.

There are certainly types of programming that I would not consider to be UI work. For example, programming a media codec is not UI work. But for every 1 codec implementation, there are about 1000 music player apps.

Now, think about your own programming. How often do you personally solve an unsolved problem? By contrast, how often do you just package together libraries that provide already-existing solutions to your problems? Unless you have a PhD, and possibly even then, I’m guessing that the latter is a lot more common.

“Hold on,” you might say, “I’m a back-end engineer. Even if I’m not inventing anything new, I don’t go anywhere near the UI.” To you I say this: think a little more broadly about what an interface is and who your users are. For example, have you ever written an API endpoint? What does “API” stand for again?

If you’re not writing interfaces for end-users, you’re writing interfaces for other programmers. They’re your users.

You can take this idea as far down as you like. For example, consider the act of writing a function. Occasionally, you write one because you have a problem that is best dealt with through recursion, or whatever. However, if you’re like me, most of the time you write a function so that you don’t have repeat the same steps at multiple points in the code. Maybe it’s for software engineering best practices, or maybe it’s to save yourself from repetitive stress injury: the point is, when you write a function, you do it to make programming easier. You are writing a UI for yourself.

But if we use the words “user interface” so broadly, aren’t we basically making the term useless? What’s even the point of this article?

The point here is that it’s important to think about all of your code as an interface, not just a black box behind a front-end. Take the above example: when you write a function, you should think about its user experience. For example here are four user interfaces for the same function.

stroke(canvas, "red", 10, 10, 45, 45, 2);
stroke(canvas, 10, 45, 10, 45, "red", 2);
canvas.stroke({from: {x: 10, y: 10}, to: {x: 45, y: 45}, color: "red", width: 2})
stroke.from(10, 10).to(45, 45).colored("red").withWidth(2).on(canvas);

When you decide which of these you want to write, you should think about the question in terms of efficiency, predictability, discoverability, and the other principles of UI design. It doesn’t matter whether you’re working with pixels or sockets, toolbars or databases: as a programmer, you use your own creativity to build something. When in comes to that thing, you are a designer.