Over the past few years, we’ve increasingly made use of design systems in our web projects. This approach helps us to think about the individual building blocks that are used throughout a project—things like buttons, menus, and typography that appear in many places.
Focusing our design and development work on these reusable pieces means that projects remain reliable and consistent as they grow. It can even help us create new projects that use the same branding more quickly than if those building blocks had to be created from scratch.
Recently our team started creating iOS and Android apps using React Native, and we wanted to make use of everything we’d learned producing design systems for the web.
What is a design system?
A design system is a set of guidelines, styles, and components that we use as the foundation of the products we build. Using a design system helps to create consistent, high quality user experiences—from visual aspects (such as typography, colour, and spacing) to interactions (such as focus states, forms, and motion).
A design system usually includes:
- Colours, typography, and space: What core styles should we follow in order to create a cohesive product?
- Components: Building blocks we can use in our code to build user interfaces.
- Guidelines: What are the best styles and components to use for different scenarios? How can we remain true to the core styles without limiting flexibility?
Moving from the web to native platforms
We love writing TypeScript and React, and fortunately React Native allows us to use these technologies to create native apps. But there’s much more to an app than the technologies under the surface. Native apps aren’t the web, and we found it important to consider this from the very beginning of a project. Whether our app is running on iOS or Android, we want to be good citizens of the platform. The app should look and feel like it belongs on the user’s device. This affects us in a couple of ways:
- Design: The design should be subtly adapted to follow the conventions of each platform.
- Development: We need to be aware of the different types of UI that can be accomplished on each platform, the APIs that support it, and how it could affect performance.
This is a little different to the web, where for the most part our UI doesn’t adapt to the underlying platform. Even though we consider common conventions, most UI on the web is custom.
But for native apps, there are some core principles we have to get right:
- Navigation: Moving between views should work in a similar way to the underlying platform. We should use the same motions and gestures as the underlying platform, unless we have a good reason not to. If possible, we should use the native navigation APIs to create an accessible, performant, and truly familiar experience.
- Menus: We should present menus in a way that’s familiar to users. Some platforms use a tab bar more widely, where others rely on slide-in menus.
- Modals and overlays: Should look and behave like the underlying platform.
- Typography, buttons, forms, icons, and other low-level UI components: These components may be small in isolation, but they have a big impact on whether an app feels at home on a specific platform.
We found testing the accessibility of native apps to be trickier than on the web, yet of course it’s vital for any app. Access to physical testing devices is invaluable. We use the screen reading software on our iOS and Android test devices to ensure that app screens are clear and usable through only text descriptions. Testing design system components in the context of complete app screens is really important to make sure they are fully accessible in real-world scenarios.
Building on native controls makes it easier to create accessible user interfaces. For example, by using the native APIs for navigation, our iOS app supports the Reduce Motion accessibility option by default, fading between app screens instead of sliding.
Physical hardware considerations
Android and iOS devices have specific hardware differences to consider.
On iPhones from the iPhone X, we have to think about how the app interacts with the phone’s notch. Full screen images, maps, etc. usually should bleed into it while making sure that important touchable/readable areas like back buttons and headings stay clear of it.
On Android, we have to be careful with what the physical back button is bound to at all times. When opening modals and similar closable views, we need to bind the back button to something intuitive, and we also need to make sure that pressing back never leads to an undefined state, such as going into a recently deleted object. This is a scenario where using native navigation APIs pays off—the less custom work we do to handle navigation, the more seamlessly we can integrate with the platform.
Design systems make this easier to achieve, because we have focused on creating granular cross-platform pieces of UI that can be composed into bigger layouts that are specialised for a particular platform.
We also have to think about the different device form-factors in use. iOS and Android run on a variety of sizes of phones and tablets. Our design system has to scale from the smallest phones to the largest tablets, which we found to be more challenging than on the web, where elements are fluid by default and media queries can control layouts. Native layouts are less innately stretchy than the web, fluid typography is more difficult to achieve, there is no grid layout mechanism, and no native implementation of media queries. We can work around these shortcomings, but the web is arguably better suited to some types of cross-platform UI development.
Finding common ground
There are a lot of details that differ between the web and native platforms, but ultimately we’re working with the same medium. Our design system has to cater to a variety of device form-factors, display sizes, and input modes—regardless of whether it’s used to create an app or a website.
While the lines between web apps and native apps continue to blur, for now they both have benefits and trade-offs. Typically, users expect a different type of experience from native apps; one that is more seamlessly integrated with their device. Thanks to technologies like React Native, we can adapt everything we’ve learned from the web to iOS and Android apps—and design systems provide a great way to think about and create user interfaces across platforms.
By thinking carefully about each platform we target, we can create a design system that feels just right for iOS and Android.
Leave your details for a callback
We'd be happy to tell you more about the services we provide and how we can help you with your business challenges.
Plan your project