Compose Design Systems: Have a Plan
We run into questions like this one a lot. They boil down to “I’m trying to use Compose Material/Material3, and it’s not letting me change this aspect”. The stock response is “Material Design is an opinionated design system”, which is simultaneously fairly accurate and often unhelpful.
So, let’s see why we’re in this situation.
What Came Before
In the beginning in Android development, there was the View
system.
This attempted to be malleable to a wide range of circumstances. Given sufficient fussing with styles/themes, calling configuration methods, and the occasional subclass, developers could hammer the framework widgets into shapes that largely met what designers might request. Not everything was configurable, though, and what aspects could and could not be configured wound up being semi-random from the standpoint of consumers of that UI toolkit.
When Google created Material Design, they first attempted to implement it purely through
themes for existing widgets, along with a few brand-new widgets. Later, via appcompat
,
they would mostly-seamlessly switch you to subclasses of widgets (e.g., AppCompatButton
instead of Button
). This did provide the Material look and feel, but it did so on
the open View
system. As a result, most of what Material implemented could be overridden,
using the same techniques that Google used to implement Material in the first place.
As a result, while Material Design is indeed opinionated, the implementation of Material Design was based on a leaky foundation, such that those opinions often could be ignored.
Compose = Structured Flexibility
Lots of things changed when we moved to Jetpack Compose. One of the big-but-subtle differences,
though, is in how widgets are defined. We look at the switch from Java classes plus styles/themes
to Kotlin functions and tend to focus on syntax (e.g., no more XML layouts). The “subtle”
aspect is that our ability to configure widgets is now limited to the composable’s function
parameters, plus composition locals to a lesser extent. Compose lends itself towards structured
flexibility, rather than the more ad hoc flexibility of the View
system.
The net: while Material Design itself did not change and is still opinionated, the Compose implementation of Material Design does a much better job of enforcing those opinions.
In terms of steering developers to better adhere to Material Design, this is wonderful. In terms of allowing developers to get their work done, this is rather less wonderful.
Let the Complaints Commence
The reason that we get these sorts of questions is because developers use Compose Material/Material3, as they feel that they have no choice. Quoting a comment on that question:
making every view of an app customized with base composables (box, column, etc…) seems an enormous and tedious job
This is an understandable reaction. We have limited documentation on implementing design systems. We have even less tooling support for implementing design systems. On the whole, Compose itself does a fairly good job of making custom design systems possible, but it feels like there has been little work done for making custom design systems approachable.
Personally, I have not found that building a bespoke design system in Compose is all that bad. Having support from things like Compose Theme helps. I recognize that I may be more comfortable with these sorts of things than are a lot of developers, though.
Have a Plan
If you are embarking upon a new Compose or Compose Multiplatform project, it behooves you to spend time considering your approach for a design system.
(if you are already knee-deep in the project, may the deity of your choice have mercy on your soul)
If You Have a Designer
Many professional projects have a graphic designer who will say what the app will look like. If you ask that designer what the project will do for a design system, you are likely to get one of three main responses:
-
“We will use this official design system: …”, where “…” might be “Material Design” or “Apple’s design system” or “Microsoft’s design system” or “IBM’s design system” or something else. With luck, there already is a Compose implementation of that design system that you can use, such as Compose Cupertino or compose-fluent-ui or Carbon Compose. If there is, make sure that the designer understands that in those places where the designer deviates from the official design system, the implementation of those places will be substantially more expensive to build and maintain. If we can limit how many of those places exist, the app UI will be as inexpensive as possible.
-
“We like design systems, and we will create our own”. In this case, make sure that software engineering management understands that the implementation of that design system will be expensive, both to build and to maintain. However, since you are using some structured design system, screens and panels based on that design system implementation will be comparatively inexpensive.
-
“What’s a design system?”. In this case, make sure that software engineering management knows that building the UI of the app will be expensive. Maintenance will be expensive if the design changes after the initial implementation. Using a design system would reduce those costs, and using an official-and-implemented design system would be the least expensive from a software engineering standpoint.
In effect, not going with a standard design system means that the designer is imposing software development and maintenance costs upon the organization. That should be an explicit decision, often by upper management, rather than a designer just deciding on his or her own.
If You Design Things Yourself
Good news: you get to choose your own level of pain!
Bad news: you have to choose your own level of pain!
Just understand that the same sort of breakdown applies as in the professional designer case:
-
Choosing an official-and-implemented design system is cheap, easy, and inflexible
-
Rolling your own design system incurs up-front costs, but ongoing work (screens) and adjustments are comparatively easy, and you have tons of flexibility
-
Not creating a design system, and instead going with “spray and pray” of UI elements, requires least initial mental energy but may make things a lot worse for you over time