Designing for Developers

November 2017

A perennial problem in philosophy of art is that explanations of beauty too easily devolve into poetry. An ambitious thinker sets out to explain beauty, and ends up writing words that are beautiful but do not explain beauty. The reader is complicit, accepting the feeling of beauty instead of its explanation.

Design shares this dilemma with beauty—it’s relatively easy to write ‘designey’ words about design, but it’s difficult to explain how design works. To give a modern example, “chamfered edge” is an exquisite phrase, but it doesn’t explain why some edges have better design than others. As a designer who intends to explain design, please don’t let me pull the chamfered wool over your eyes.

How is designing software for developers different from designing for people in general?

The most important answer to this question is that it isn’t. People are clever, sensitive animals, and developers are a kind of people. Too often when we ‘design for Group X instead of Group Y,’ we think of Groups X and Y as mutually exclusive. When designing for developers, it’s important to never lose sight of their fundamental humanity or treat them as a narrow stereotype. People love delightful software. Developers are people. Therefore, software for developers should be delightful. This has been the core of my developer design ethos since I joined Xamarin in 2012, and is a perspective my team brought with us when we joined Microsoft.

But, really, what’s different about designing for developers? Do developers have bigger brains? Do they ‘see code’ like Neo in the Matrix, or ‘think in numbers’ as many people imagine? Do they have more fingers than non-coders? Sadly, not usually. Ask anyone who wasn’t a developer last month, but who read some tutorials or attended a bootcamp and is now happily writing code, if their intrinsic capabilities have changed.

What’s different about developers is the class of problems they solve, the style of reasoning they apply to these problems, and the inherited constraints of the systems with which they solve these problems. For example, developers collaborate on a huge number of formally structured text documents (code), reason about tradeoffs between power and time (analysis), and spend a lot of time searching for nearly invisible defects in large, confusing systems (debugging).

When working on code, typing is more useful than clicking or tapping. Therefore, designers should recommend keyboard-driven interfaces that emphasize shortcuts and search. Pointer-driven or touch-inspired interfaces are poorly suited to this kind of work. There are incredibly productive ways to create programs that don’t involve typing any code, they just haven’t been invented yet. For the time being, code and typing are the bedrock of developer design.

Analysis helps developers visualize and understand the dynamics of their programs—how much memory does my program use? What are the latencies of the various subsystems and functions for different inputs? This is still an early art form, but the necessity of correlating these visualizations to the underlying code suggests that visualizations should display interleaved with code. Investing in editor surfaces that make it easier to draw alongside text will help us discover new ways to understand our programs more deeply.

Debugging combines code and analysis–you want an interface that’s great for reading and navigating code, and also great at visualizing program dynamics, to help you discover, understand, and finally fix bugs (or just wrap a suspicious swathe in a try-catch and go for an espresso). As a proponent of statically typed, purely functional programming languages, I believe in improving debugging by making bugs impossible to write in the first place, but if you’re writing JavaScript, you’re going to need all the help you can get! Inspecting the state of your program, and specifying criteria for when the debugger should pause to give you a look around, are important areas of concern for designers working on debuggers.

Beyond writing, analyzing, and debugging code, developers collaborate with each other in unique ways, and orchestrate complex planning and deployment processes that introduce even more interesting design considerations. I hope I’ve left you with enough to think about for now, and will explore these ideas later!