Know your medium
The benefits of designing in code
Earlier this week Frankie and I published a post on the NHS’ Design Matters blog about prototyping in code and the work we’re doing to improve the NHS prototype kit. The post is part of an initiative across NHS England to re-centre our working practices on common foundations using open, accessible technologies. It is an approach that has been popular across the public sector in the UK for a long time, but over time tools like Figma have come to dominate working practices in many places. We wanted to put down a marker that describes our view on the subject and what we intend to do about it.
I want to expand on one of the benefits we outline about prototyping in code. In the post, we wrote that
it allows designers to understand the medium of the web, and its benefits and constraints, in greater depth
This isn’t the main point most people emphasise when talking about designers working in code or making coded prototypes (it wasn’t even in the post until quite late in the drafting process), but it is the one I care most about. To be clear, making prototypes accessible and using the real front-end components is important, but the greater depth of understanding and fluency in your media of choice that comes from getting your hands dirty has benefits that extend across the entire design process. Knowing what your materials can and can’t do is a foundational skill that is easily missed if you only ever look at pictures of interfaces. Working directly in code changes the way you design.
After we published the post, Ananda reminded us about Frank Chimero’s article The Web’s Grain. Its core thesis is right in the subheading:
Every material has affordances. What if we started thinking of screens as a material for digital design?
I remember reading this back when it was originally published in 2015 and nodding along enthusiastically. It rhymes with the way I learned to think about print media, and books especially: paper and ink and glue and thread all have physical properties that you can consciously manipulate to create a desired effect. Books are, first and foremost, physical objects whose tactile qualities speak through how they have been arranged and combined. For example, paper has a grain and if that grain runs in the wrong direction (left to right), the book will feel stiff. If you change the paper’s orientation so that the grain runs vertically, the book will open better, the pages will bend more easily, and the book will be softer. Basically: it will feel better in your hands. But before you can can choose how to orient the paper to gain the desired result, you first need to know that this even is a quality of the material. You need to first know what the material’s nature is.
Designing for digital media is much the same. Different operating systems have their own design idioms and the only reliable way that I’ve ever found to get to grips with them is to make working software for them. There is a huge variety of programming languages and interface frameworks to work with; each and every one of them has a set of in-built possibilities and limitations. Understanding what those are will help you know what design ideas will be easy to execute and which will be really hard to pull off. Having that understanding can save you time and it can inspire new ideas. Constraints are often generative.
I’ve never been able to finish design work in layout tools like Figma or Illustrator. I can get close, but never quite fully there, never quite fully done. Once built, the thing always seems just a bit wrong. There might be a problem of translation between designer and developer, but most of the time the issue is that the details of the layout just feel different when rendered through different technologies. Subtle differences in scale or the way the layout reacts to changing screen dimensions add up to something that is sloppy.
One of the most significant changes to the experience of doing design that comes from working directly in code is that it forces a shift away from how something looks and toward the way it works. When building out a working prototype, the designer will need to think through how their product or service changes and moves when the user interacts with it. Anything that can happen in the product needs to be thought through and designed for. You might try to simulate any and all interactions with a visual layout tool like Figma, but it will never completely reflect reality and thus your work will always fall short of being as precise or as thoroughly considered as it could be. It is far more effective to just build the thing and tinker with it until it works.
For a snappy breakdown of how the work changes when working in code, check out this video about the design of Notion Mail and skip to 14:20. The designer talks through a set of design decisions that simply could not be made in a layout tool alone. That these decisions even need to be made might not be apparent until you have working software to play with.
To a significant degree, the tools we use determine what options are thinkable. Today, tools like Cursor and Lovable provide designers with ways to get working code-based prototypes (and even fully functioning software) up and running quickly. The challenge with this approach is that it has become easy to produce working software but the designer will, by and large, have skipped the process of getting to know what their tools are inclined toward. For instance, in the experiments I’ve done with Copilot to build iOS prototypes, I’ve managed to produce a basic list component at least three different ways. Which is the “correct” way? Does this matter? Copilot has no consistent opinions on this, so it falls to me to read the docs and then ask Copilot to refactor the code. The degree to which this approach helps the designer understand their medium is questionable, but I am interested to see if the trend is a long-term net benefit, and I’m happy that more designers are producing coded prototypes.
Mandating that designers work in code and use the NHS prototype kit isn’t about insisting that everyone become a expert developer. That wouldn’t be practical and it isn’t necessary. It also misses the point: teams have developers who know about all manner of stuff beyond how to whack together a prototype to test some ideas. Rather, working in code helps designers think programmatically. It helps them understand how to use data and how to collaborate with technologists. Working in code is a means for developing a common vocabulary for the team and executing work at a higher level.