< back to all blog posts

Native apps and design systems

Illustration of a desktop computer

A lot of what’s talked about with design systems tends to be very web-centric and with good reason. It’s relatively quick and cheap to deploy new designs to a website over a native app platform. Let’s look at some of the options you have if you want to bring your native apps closer to your design system.

Alignment

Right at the beginning of bringing your native apps (iOS and/or Android) close to your design system, there are some initial questions you can ask yourself to be clear about what you’re trying to achieve:

  • Are you considering your apps to use a shared look & feel?
  • Do you consider your apps to be very different from your website?
  • How much alignment should there be?

While the web is more open to how we present our components through applying CSS to HTML, native apps platforms have design constraints and conventions to make experiences feel more appropriate to these platforms. I’ll look into design specifics a little later on, but how tightly bound we want our design system sets the groundwork for how this might play out through design and development.

Alignment might be anything from working in similar ways, using similar values to sharing design tokens to having our documentation reflect all platforms we publish to. Assuming you want the latter option, how close you consider web and app implementations to be will affect how you proceed.

Some examples of that might be:

  • Include the apps team(s) in conversations about the design system from the earliest stages
  • Discuss ways that enable enough similarities in design files and codebases with ways of working that might enable more collaboration and closer alignment further down the line
  • Look at areas where naming conventions could be aligned
  • Design tokens:
    • Aim to share the values associated with design properties in some way from a core set of tokens
    • Consider whether your web and app outputs should cater for multiple themes
    • If themes are used, consider whether they have similar enough executions that the token structure could provide for all outputs.
    • Using a tool like Style Dictionary, look at how consumable output could be generated from your design tokens and how that be pulled into builds

It’s worth having a read of my colleague Jules’ articles “How to define your design system’s flexibility” and “Finding the right balance between consistency and flexibility for your design system.” You can build on these processes of exploring the application of brand and defining flexibility in your system, extending it to where similarities and differences may be needed and desired across platforms.

illustrations of 3 computers

Design

In our design tools, the structure we’ve looked at needs to be somehow executed. When it comes to the details of a component, it’s important to recognize that the same component may often be expressed in different ways. Using a typical button component on the web, we have little to no constraints over how these should look as we style out <button> or <input> tags with CSS.

If we look first at Apple’s guidelines for buttons, there may be terms or contexts of use that we might not come across on the web. There are also differences between their platforms, should you venture towards macOS software or watchOS apps. Buttons are largely the same, but given the conventions of the platforms, you may find they differ slightly.

This example could make sense on any platform but might not be how we’d think for the web. Here, we know the constraints of the specific devices we’re designing for. So, we have a modified set of constraints with the interaction method and pixel-perfect positioning.

Make buttons easy for people to choose. On a touchscreen, buttons need a hit target of at least 44×44 points to accommodate a fingertip. On all screens, it’s essential to include enough space around a button so that people can visually distinguish it from surrounding components and content, whether people use touch, a pointer, or a system that expands a button when it’s in focus.

Here, for watchOS, there’s a difference between use cases within the same platform. While we might not all be making apps for the Apple Watch, it shows how there can be differences in ways that we might not initially appreciate.

Screenshot from Apple’s watchOS HIG showing how native UI elements might need to look different on a device

Jumping to Android’s Developer UI Guidelines on buttons as an example, you can see some, but not all terms are similar to what we might use on the web. Over on Material’s buttons docs, there’s guidance here that feels quite similar to other platforms but has reference to a floating button that we might not have on the web in the same way. The button itself may be the same or similar to others you already have, but that context of use might need a different visual presentation that might not exist across your other platforms.

Across this guidance, you can pick what you find to be consistent and highlight where divergence is needed. They’re the same buttons conceptually, so relatively small changes give us the ability to express them across platforms.

Design tokens

Exploring design tokens and strategies for working cross-platform is a big area! Some of this can be done on a high level by considering your alignment piece and working out a token hierarchy. You may require themes, platforms, and multiple products, so starting with what needs to be consistent for everything in what might be a reduced core set of tokens, then introducing layers of specificity to create relationships between these layers that help to generate the kind of outputs you’ll need.

There are decisions about storing platform-specific values or allowing automation to translate value to the appropriate format. The former means you can have fine-grained control across platforms for what a semantic value might hold, as a value intended for the web may be 16px. For a native app platform, you might want 10dp, which would result in a different outcome for the same semantic token. The automated route would translate your 16px into the format needed for your native app as part of a build process.

illustrations of 3 computers

Documentation

Seeing these archetypes of our components being the same thing where it makes sense, isn’t the end of the story. A button is a very simplistic example. Menus or navigation may have different placement and needs across platforms, or more complex components might diverge significantly to meet the needs or expectations of each platform here; we need to find the balance of meeting conventions with still feeling on-brand.

When it comes to documenting what you have, highlighting differences or what platforms a given component applies can often be the right move. Still, your internal structure or ways of working might mean it makes more sense to separate platforms despite their apparent commonalities. There’s a further problem to overcome when you want to actually show your components in your documentation, as you might already do with your web equivalents.

There are a few scenarios that I’ve seen that might help you…

Don’t show the actual component

This isn’t quite doing nothing, as the docs should still talk about how to use and consume a component and give code examples, but as native platforms can’t render on the web by default, showing the actual, live, coded component in the documentation doesn’t happen by default. You can highlight the differences or divergences between platforms, so it’s clear what has been done intentionally to have their output in the right way. You can certainly pull in the design for reference!

Demo app

This concept is to have an app that follows the structure of your design files structure, much as your web-based components should for tight alignment between disciplines. This skeleton or demo app would show all of the components that could either be run by a developer in a simulator or released for internal users to download to their devices. There’s still an inherent disconnect between these apps and other platforms, but the audience needed to access them would often be much smaller than the overall design system documentation. This suggests alignment more than full integration too.

Tighter integration

Looking at what Storybook Native offers, it works with a service called appetize.io to be able to render your apps on the web and present them in a similar way to Storybook’s other platforms, using controls to manipulate the component within the app preview. This is likely the closest integration you can get. Using Storybook’s composition mode, you could pull all of your platforms into the same URL.

The great thing about that is either using Storybook Native or Appetize, you can embed that directly into zeroheight to show how the components render across any platforms you work with. If this workflow works for you, this brings not just design artifacts but the actual components from multiple platforms to one space, bringing real transparency to how everything currently is across the ecosystem.

illustrations of 3 computers

Deployment and change management

Another obvious difference with native app platforms is that deploying code changes works very differently. While the web can be pushed live often very quickly when a change is wanted, native app platforms almost always need an update to the client app…which means all of your users updating. You’ll find your user base using a range of versions of your app at the same time, though through auto-updates, this isn’t always as problematic as it once was but still a challenge.

Seeing the path to getting design work through to end users resulting in different paths and timescales needs to be factored in from the beginning. Platforms may be out of sync for a time, updates taking different timescales to deliver and for the end users to actually have on their devices. Trying, through solid governance, to be clear on what DS changes might be in a client release and times when certain design changes might need to be batched in a release together to ensure the user experience remains as good as it can be.

Change management can be overlooked when it comes to design systems, but when working with native apps, it’s very apparent how important this is. What differences are we OK with when app versions may be out of sync? Are there changes you might want to be released across all platforms at the same time?

illustrations of 3 computers

What can you do?

You may not bring your native apps into your design system space from the beginning, but alignment and a sense of what is possible are really important and valuable. Having teams from different domains aware of similarities and differences and how alignment can be a simple and powerful step to enable future change is a big step.

Early changes may include considering how CSS or web-centric your language or storing values may be. Enabling the storage of design decisions across platforms from our design tools and design tokens opens the door to this greater collaboration between very different user experiences. It’s worth reading this article by Danny Banks based on his talk from Clarity Conf in 2020 about ways to think about structuring multi-platform design systems.

This isn’t a set of challenges that we’ll all come across but it does help us reevaluate some of the methods we use to ensure we’re open to future platforms or changes in technology. It’s both about short-term needs and a longer-term strategy to ensure the design system can be built in a robust and extensible way.

We’d love to hear more from people working across platforms so drop over to our Slack community zheroes if you want to share your experiences!