Product Design / Toolbox

Interface

Interface

Product Design / ToolboxNovember 20, 2017 · 6:27pm · (Edited 9 months ago)
In this post, I’m going to lay out a case for an intermediary format between design and engineering tools to enable more efficient, capable tooling for product teams generally and designers especially. This proposal is based on a series of conversations I’ve had with small groups of designers and engineers over the past year or so. 
If we can provide appropriate context, our computers can do the work of translation between design and development processes for us. This should remove a significant amount of work and confusion between teams and enable individuals and companies to focus on harder, more important problems.

The purpose of UI design

A software company’s purpose is to solve some problem for a user. An effective solution can be enabling new behaviors, making existing processes easier, reducing cost, or simply giving people something they enjoy. For any of those things to happen, a product needs to ship to an end user.
This maps directly to the purpose of any interface designer’s work - which is to compose an interaction layer for software that enables users to access solutions to a given problem set. If a user is unable to do so, the designer of that software is not done yet. Therefore, a designer cannot be done until the product has shipped.
As a note, I’m distinctly separating “interface design” and “illustration”. Illustrations often appear in interfaces or alongside products, but the processes and tools necessary for successful instances of each are enormously different. If you call yourself a UX designer, product designer, interaction designer, or something else where your output is meant to lead directly to the production of user-facing software, I’m putting your work in the bucket labeled “interface design”. If the final product of your work is an image, icon, illustration, typeface, advertisements, print media, or some other visual communication medium without native interactivity, I’m putting that work in the “illustration” category.

The problem with UI design tools

Every popular design tool available today is optimized for illustration. The tool’s marketing site and documentation might talk about the intersection of design and engineering, provide tutorials on how to compose design systems, and the artboards might come in common screen sizes, but they are ultimately optimized for drawing pictures. For proof of this, look no further than the toolbar of your current design tool:

Pen tools were designed for illustration. Shape layers were designed for illustration.
A common argument for the current model of design tools is that they allow you to directly manipulate layers to create quickly and accurately. For UI design tasks especially, this is a false assumption. They’re an imperative abstraction on top of a set of properties determined by inappropriate primitives - rectangles, ellipses, vectors - for the task that is required of them. Because of these primitives, the material output of design tools based on visual primitives will always be an image at best. This is great for doing icon work or spot illustrations in your UI, but adds significant friction to the process of building the interface itself.
A quick example: some design tools attempt to provide a basic description of your UI in code. The problem is that your tool thinks the button you designed is a rectangle with rounded corners, not a button, so any code it provides is only marginally useful - if at all.

The design tool’s code output is antithetical to how components are built in production. As a frontend engineer, there is no case in which I would paste this into my codebase. Some of the values are useful, but the property declarations don’t have enough context about the intent of the design to provide significant benefit to the programmers they’re built to serve.

What You See Is What You Get

For a long time, there have been WYSIWYG engineering tools that market themselves as design tools - Webflow, Dreamweaver, RapidWeaver, and Macaw are all examples of this. These are outside the scope of this conversation because they focus on code output for specific platforms with specific methodology. This kind of tooling is great for freelancers or solo designers who need to design, code, and ship by themselves (especially if they don’t have the benefit of being able to take the time to fully learn to code) but they don’t enable teams at scale or effective cross-platform design.

Common inefficiencies in design

UI designers love doing busy work and our tools are wonderfully effective at this purpose.
  • Manually nudging and meticulously adjusting alignment are inefficient methods of creating consistent spacing across an application.
  • Reorganizing groups, artboards, pages, and files rarely contributes to shipping.
  • Drawing flow charts to indicate user paths and routing is a massive timesink and the maintenance cost is significant.
  • Redrawing elements from an app after you find out your static design wasn’t accurate to production rendering is a repetitive process that leads to confusion on future iterations. 
  • Attempting to manage design systems manually across incompatible formats is a full-time job that always results in inconsistencies.
  • Iterating on designs without testing them with users lends itself to product decisions that are detached from the market’s requirements. 
  • Attempting to emulate system elements by building UI kits and sticker sheets is recreating work that is already done more accurately elsewhere.
We, as an industry, lose hundreds of thousands of hours per year on these mundane, tedious, ineffective tasks. We gain nothing new from them. We don’t get to work on harder, more important problems because we’re expending our time and effort on minutiae that feels like progress. All of this tedium is a direct result of the separation of design and development processes.

Getting on the same page

The goal of any UI design tool should be to provide visual controls to enable anyone to ideate and create interfaces quickly. To be more effective, we need data interoperability between design and engineering tools. If your UI design tool knows that it’s making UI for a given platform, you can build with elements that map directly to components in your codebase. Once there’s correlation between properties (whether directly or due to custom mapping), components can be passed back and forth freely between tools, effectively integrating the design and development processes into one cohesive, omni-directional unit.
This interchange system should be a simple declarative model based on UI-specific primitives (think button or input vs rectangle or ellipse) with only slight abstraction over the actual properties if any.
Example: I’m a designer working on a sign-in modal within an app for web (in React).


In the instance of the “Name” input above, a design tool sees a group called “Input - Name” that contains a rectangle and two text layers - one for the text value and one for the placeholder text. 
The React component sees an HTML <input> element with several inherent properties and states available to the programmer. Each state needs to be designed, but unless I go to the MDN page for each element and read through its API properties, I likely don’t understand the full scope of the work I’m setting out to do. Which means I’m really just designing the states I can think of off the top of my head.
On one hand, I’m effectively designing blind but for my own experience. On the other hand, the tools I use for programming tell me everything I want to know about what I’m building - which properties are available, the syntax for them, and they even try to autocomplete properties for me! These features help me to avoid mistakes and tell me what kind of data each element needs - but design tools have never had such a mechanism. 
What if there was a UIKit syntax plugin for your design tool that added new iOS-specific primitives so you no longer need to draw buttons by way of rectangles, but instead choose an actual UIButton in the toolbar, insert it into a View rather than an artboard and simply begin adjusting its actual native properties?  Your design tool could then:
  • tell you that the icon you’re trying to put inside your button should be 25px × 25px when you’re designing @ 1x (resolution probably doesn’t even matter anymore for most tasks) and automatically configure the export settings for the asset and push them to your team’s asset library
  • let you know that you still need to provide highlighted and disabled states for your button and then show you all your states side-by-side when editing them for easy reference
  • automatically apply default padding when you put your button into your UINavigationBar or automatically reconfigure your tab spacing when you decide it should go in the UITabBar instead
  • allow the button to accept a route property that points to another View in the app to navigate to when you click on the button
  • auto-generate a flow-map for your application based on route properties
  • handle routing and TabBar behavior when you decide you want to see how it feels. Maybe even compile a basic version of the interface so you can test it in Simulator or on your phone.
You as a designer become much more effective because your tool actually has some concept of intent.

Interface: a proposed intermediary format

An ideal interchange format would be a description of an interface as a data object that functions as a translation layer. This could be in an industry standard format such as JSON where values could be mapped to appropriate properties on a case-specific basis determined by which platform or language you are intending to ship to. Components can be described by diffing component and state instances against their default properties - essentially exposing component inheritance. By moving your source of truth to an open source, moderately-abstracted textual description, both sides get many benefits.
  • existing syntax definition packages could be used as a way to determine new sets of primitives
  • tool publishers can choose which properties to read and write enabling specialized tooling for specific purposes (e.g. prototyping tools could write animation or routing properties, while icon design tools could write asset references, and dev tools could write function or data API references)
  • references written by one tool could be used by another tool (e.g. data references provided by engineering tools could be read by design tools to ingest data from a production API, style properties could provide styling code to the engineering codebase)
  • generated code could be modified to support your team’s code formatting, modules, and components so output from this system could feel like code written by another team member
  • as a text file, it can live in the same version control repo as the rest of the application’s codebase
  • linting, testing, and formatters can be used to find errors and format code prior to committing to a repo

Here’s an idea of how I think it could be structured:
// interface.json //tell your tools which components/syntax to load "platform": ["iOS-UIKit", "myTeamDesignSystem"], // UI components are defined by making declarative property changes against system primitives or imported from existing definitions (e.g. design system) "components": [ { "favorite_row": { "primitive": "UITableViewCell", "properties": { "padding": "16px", "tint": "{myStyleGuide.palette.blue60}" }, "children": [ { "primitive": "UIImageView", "properties": { "aspect": 1, "src": "http://images.com/something.jpg" } }, { "primitive": "myColumn", "children": [ { "kind": "text", "type": string, "data": "{{name}}" }, { "kind": "text", "type": number, "data": "{{phoneNumber}}" }, { "add_favorite" : { "primitive": "UIButton", } } ] } ] } } ] // application is defined as a data object with references to external sources "application": { "name": "Phone", // routing and navigation can be defined at the root level (some will need to be defined at lower levels) "root": { "kind" : "tabs", "screens" : ["favorites", "recents", "contacts", "keypad", "voicemail"] }, "screens": { "favorites" : { "component" : "UITableView", "content" : [ { "component": "favorite_row", "content": { "name" : {myData.user[n].name}, "phoneNumber" : {myData.user[n].phoneNumber} "route": "favorite_view(myData.user[n])" } } ] }, "recents" : { // TODO }, "contacts" : { // TODO }, "keypad" : { // TODO }, "voicemail" : { // TODO } }
If we can get our different toolsets talking to each other, we can work together more effectively with shared language and less overhead. Designers can have as much freedom as developers do to move between specialized tools to accomplish a purpose, without loss of work or fidelity. I believe this needs to be an open source solution so that tools can be built and maintained publicly though manufacturers could define new properties and adapters by means of vendor-prefixes if a property isn’t standardized.
This interoperability would hopefully do for design tools what it has done for engineering tools. Our tools should be better by being able to specialize while contributing to a central unit, thus allowing us to stop building the same massive feature sets as every other tool and instead specialize and move the field forward. You should be able to move from any design tool to any other design tool with minimal configuration.

Where we start

Right now, some features of this could be built on top of symbols and component systems in tools with plugin APIs. That would be hacky, but it’s possible. 
There have been attempts at similar interchange formats in the past, but they have traditionally been tied to a single manufacturer, so logically, this probably starts small with up-and-coming, community-driven projects and open source IDE plugins leading to successively larger tool publishers coming onboard and eventually organization of a core team or working group to manage an extensible standard if it gains traction. If you work on design tools or maintain syntax packages and plugins for IDEs and you’re interested in driving this forward, please get in touch. It’d be awesome to see the our industry make some huge leaps forward so we can focus on bigger problems.
This is by no means a finished document, but hopefully a starting point for a larger conversation that leads to real improvements for our industry and makes us all better at what we do. Please jump into the chat below and share with others!
Thank you to everyone who has helped inform and develop these ideas over the past year: Payam Rajabi, Sam Soffes, Diana Mounter, Max Schoening, May-Li Khoe, Adam Michela, Josh Puckett, Carmel DeAmicis, Sho Kuwamoto, Kris Rasmussen, Rasmus Andersson, Daniel Burka, Josh Brewer, Tom Moor, Kevin Smith, Marc Edwards, Drew Wilson, Danny Trinh, Brent Jackson, Adam Morse, Ben Wilkins, Jon Gold, Lucas Smith, Pasquale D’silva, Jake Marsh, Rylan Barnes, Vlad Magdalin, Linda Pham, Sergie Magdalin, Barrett Johnson, Koen Bok, Jorn van Dijk Brian Lovin, and Max Stoiber

November 20, 2017 · 6:52pm

This is awesome! Great read Bryn! I love the idea of having platform specific primitives in which you're adjusting actual native properties. That would be amazing.

like-fill
12
  • reply
  • like

This may be a naive question but how do you see these tools or toolsets scaling and growing as development tools, requirements, languages, etc. change? \

like-fill
4
  • reply
  • like

There are so many great ideas in there! Thanks for sharing your thoughts on that! 👏

like-fill
4
  • reply
  • like

@neversitdull I think that would need to be similar to syntax packages for IDEs. There's no way one team could manage it, but if the tool manufacturers provides APIs for features in the spec (similar to Atom/Sublime/VS Code)... I think it's doable.

like-fill
2
  • reply
  • like

I was nodding the whole way through this post.

> choose an actual UIButton in the toolbar, insert it into a View rather than an artboard and simply begin adjusting its actual native properties?

Have you seen Modulz? I'm working on something along the lines of what you're describing here.

https://twitter.com/colmtuite/status/909792399924318209

No reason why it couldn't export to interface.json

like-fill
9
  • reply
  • like

I have! That'd be awesome @colmtuite!

  • reply
  • like

I think that misses the point. You, in whatever role you see yourself, should be able to use the best tool for the job you’re trying to accomplish without having to redo work. Whether that’s building a component, defining routing, or defining behavior. You should only need to do the same task once.

like-fill
1
  • reply
  • like

maintaining design systems as a task shouldn’t be a full time role, it should be the source of truth across roles and a way of staying in-sync rather than something that needs to be kept in-sync itself.

like-fill
11
  • reply
  • like

@steved Exactly! Ideally the definition work would be done once and the iOS/Android work would just fill in the gaps with better-suited tools for the task!

  • reply
  • like

I really like this @bryn! It resonates a lot with me as a designer who is frustrated with the current state of design tools and their inherit limitations given they are meant to generate images.

like-fill
1
  • reply
  • like

A point of feedback and discussion on the proposed format: It seems like what you put above only addresses static components.

like-fill
1
  • reply
  • like

From my experience, a lot of interface complexity rears its head in two cases: when you take into account component state, and the context of each component. What I mean by context is the device the interface is on, or properties of that device (for example, if the device is turned horizontally, or the interface being on an iPhoneX device vs. a iPhone 8).

like-fill
3
  • reply
  • like

I understand this proposal is early, but do you have any thoughts on how the format could address this?

like-fill
1
  • reply
  • like

I didn't handle it in the format example specifically, but I did mention it above. I think component reflow should happen at the view level, and I think component state could be handled in a nested object inside the original component, or when it is instantiated.

  • reply
  • like

there certainly needs to be handling for this for my example above with the UIKit syntax to work at all

  • reply
  • like

@bryn Product teams should basically never do the same thing twice. I think what you're describing would be a great place to be at at some point. I think we can start by looking into each of our small processes and look how we can improve those. They should lead us to an open, interchangeable format that you're describing.

It can be as small as changing the copy on a design. If there is back and forth between the designer who edits the file and renders a flat image and the content strategist who comments on those flat images. Why can't we bring those people closer together?

If we're doing this we realize that the "handoff process" might not be as good as it can. Designers rendering flat images of their potentially powerful structures in Sketch/Figma/Adobe XD, is a total loss in depth.

Anyway, great read! 👏

like-fill
8
  • reply
  • like

Great post. Been drafting some similar thoughts, but no where close to this fidelity. Interested in your thoughts on where rectangles and pen tools shine: rapid, generative sketching of non-existing patterns, @bryn. I.e. aggressive forking of existing components in cases where completely new views are needed

  • reply
  • like

Good question, @dannywhite! I think non-existing patterns are rarely created, and rarely the right approach to be honest. There's certainly room, though. I'm not advocating for removal of those primitives (Illustration is great and you should be able to illustrate using good illustration tools!), but more for the addition of UI-appropriate primitives that are determined by a standard.

like-fill
2
  • reply
  • like

November 21, 2017 · 8:35am

@bryn great post. 100% agree. The reason I joined Fuse in the first place was because I realised that in the process of making a great app development platform, they created a really powerful design tool. What you are describing is basically a more platform agnostic version of our UI layer, written in JSON instead of XML. I also think this problem will be solved by making design an indistinguishable part of the product development cycle. I don't think UI tools are best positioned to make that happen.

like-fill
2
  • reply
  • like

Love this Bryn. I've also been thinking about how design tools are limited by language. We can typically design for out native language. But we so often ship in multiple. No design tool is set up to quickly change language and filter through the design accordingly. This proposed format could certainly help that.

like-fill
2
  • reply
  • like

very cool read, bryn. would love to see where this leads!

like-fill
1
  • reply
  • like

Love this @bryn. I’m very interested in this. Recently I've been looking into tools created for specialized purposes like creating car dashboards/HUD's and there's so much advancement in this space. We might take notes from this industry: Some of these tools lean heavily on API's, binding data to objects to assist with jobs like logic within the interface, localization, and automation. More and more I feel our tools should integrate tightly with one and another, this could bring teams and disciplines closer together.

like-fill
7
  • reply
  • like

Awesome read @bryn.

I totally agree with everything here and your syntax is actually pretty similar to what we are using for https://interplayapp.com/

I'm going to be in San Fran next week for 2 weeks and would love to catch up to discuss more.

like-fill
1
  • reply
  • like

Nice post! Wish I could thumbs it up 👍

like-fill
1
  • reply
  • like

Side note: I like the idea of using Spectrum as a blogging tool.

like-fill
3
  • reply
  • like

This is a great post - one I think I'll be re-reading and quoting to colleagues.

I'm particularly intrigued by where we could possibly go with this particular idea of yours: "auto-generate a flow-map for your application based on route properties".

Imagine having integration with QA tools that would enable high-level testing to take place ahead of build, teasing out interesting edge cases to design for.

like-fill
1
  • reply
  • like

Massive props to you and your team!

Please keep at this...

like-fill
1
  • reply
  • like

Hi, I've been writing about something similar, the need for UX source files:

https://medium.com/proof-of-concept/creating-a-true-ux-tool-part-1-source-files-46faa29094cfhttps://medium.com/proof-of-concept/creating-a-true-ux-tool-part-1-source-files-46faa29094cf

I'd love to get in touch and share thoughts.

Best regards, Julius

http://www.trueuxapp.com/http://www.trueuxapp.com/http://www.trueuxapp.com/

  • reply
  • like

@bryn, _stop it_. I continue to feel pain using Sketch for UI design, and I don’t need you reminding me again.

like-fill
1
  • reply
  • like

But seriously, thank you for this very thoughtful post. There hasn’t been a great leap in our tools yet, but I feel like it’s going to be soon.

like-fill
2
  • reply
  • like

I especially feel the pain of, *‘Attempting to manage design systems manually across incompatible formats is a full-time job that always results in inconsistencies.’* One thing that I wonder about is how Interface will deal with complex dev. environments, dependencies, and all that. Dev. environments at my work are exceedingly complex, so I balk at bringing that pain (back) into my work as a designer. (I used to write front-end code at this job, but the dev. env. and legacy code were two huge pain points that made me want to just design.)

  • reply
  • like

@philsoutside: right? I stopped using design tooling for mockups at all bc we need to move fast and everything just gets redone from scratch in code.

like-fill
1
  • reply
  • like

I'd rather just design in code until *all of the work I do* can contribute directly to the end product with no manual reproduction

  • reply
  • like

(that said, I do use design tools for illustration/icon work - which they're great for)

  • reply
  • like

I think dev environments are magical when they're well-maintained.

like-fill
1
  • reply
  • like

Just thinking of all the behavior my IDE has due to open source tooling defined by standards makes me super excited about what abilities design tooling could have

like-fill
1
  • reply
  • like

I am guessing you’ve used https://compositor.io and you said you’ve heard of https://www.modulz.co (that name tho 😬) — Are these not heading in the right direction when they’re more mature? Where have you found them to fall short?

  • reply
  • like
  • reply
  • like

And you weren’t very fair to Framer. 😉 Their code-centricity really sets them apart from these other illustration tools. Still, it falls short from your vision. Your point about the disposable nature assets is true of Framer. They are aware of this, and I bet they will get on top of this (as they’ve started to ship partial solutions to this). Your other point about design tools being ignorant of real components is keen (only seeing rectangles). Framer doesn’t solve this either, but I feel like they are best suited to nail this as well, particularly because of the code-centricity. 💅

  • reply
  • like

I've def used Compositor, and looked at Modulz. I don't think these are headed this direction (at least, yet) as they're extremely platform-specific.

like-fill
2
  • reply
  • like

also, dev-oriented

like-fill
1
  • reply
  • like

I've talked to Koen and Jorn quite a bit about this (forgot to include them in thanks 😅) and I think it has the same dead end as every tool, despite its code-centricity.

  • reply
  • like

(thanks fixed)

like-fill
1
  • reply
  • like

November 22, 2017 · 11:19pm

This is a really interesting perspective and I find myself agreeing with more and more. When InVision announced Studio, I remember feeling excited but also skeptical in it actually solving the problem. With your post, I realized that the problem isn't with the tools, it's with the workflow (and our understanding of the workflow), and I think what you're proposing is a better workflow between design and development and with that, the proper tool.

like-fill
3
  • reply
  • like

Relevant to this discussion: https://github.com/airbnb/Lona

like-fill
3
  • reply
  • like

indeed @bomberstudios - seems to be same intent with slightly different goals (theirs seems to be aiming for cross-platform with same data. I'm a little skeptical of that piece.) but they definitely emphasized the omni-directionality of flow across tool, which I think is very important.

like-fill
1
  • reply
  • like

November 23, 2017 · 8:43am

This has been on my mind for some time too, but this write up is much more thorough than I could've imagined. Thanks for that @bryn!

At the Sketch Plugin Hackathon that we organized in Berlin there was a team that made a proof of concept of the `.svgsymbol` file format that aims for omni-directionality and cross-platform design/dev. Even though the PoC was limited to working with Sketch & Framer, I can see it as a first step (like you mentioned) that could go in this direction for building on top of the current structures of symbols/components and map that to a codebase.

See more here: https://github.com/gerrit/sketch-svgsymbols

And the recording of the hack demo here: https://vimeo.com/242445551#t=23m55s

What do you think?

like-fill
1
  • reply
  • like

November 27, 2017 · 8:48am

https://github.com/kovchiy/beast — looks relevant (mostly in Russian, but at least you can check the syntax)

  • reply
  • like

great post thank you - I'm currently having this exact problem with our design to engineering and back again, in some cases engineering may change some elements and then create some 'design debt' that we need to update back in our design system within Sketch. We've looked at the React Sketch plugin which would help but its not great, this would definitely be the direction forward!

like-fill
1
  • reply
  • like

As a designer whose full time job is basically updating and maintaining a UI library alongside a custom CSS framework and Angular module architecture... this resonates with me on a deep level. Will be paying close attention to the conversation in here! Thanks for kicking it off @bryn

like-fill
1
  • reply
  • like
Your message here...

*bold*_italic_`code````codeblock```