Design systems are hard. Building Ditto 2.0 made design systems even harder.
We didn’t have an established design system. We knew we needed one, because it would multiply our velocity down the line, create consistency, and solve a swath of known usability issues systematically.
But a design system in this moment was a design system being built in conditions of high uncertainty: legacy product constraints, anticipated iteration, and a rebrand, all at once.
We had an existing product we’d strategically decided to build Ditto 2.0 alongside—we’d work in slices that we could ship and learn from as we went to avoid doing a “big redesign up front.” This meant we needed Ditto 2.0 to fit in with the legacy product as best it could to avoid the product as a whole feeling fragmented, which would be a negative signal towards our quality and craft.
We anticipated, correctly, that shipping in slices and learning as we went would lead to iterating on our ideas, in significant ways, which would affect the product UI built on the design system—but in this moment, solving problems in the product came ahead of strict alignment to the system.
And the existing product wasn’t built with an existing system. It had all kinds of UI-related usability issues and reflected a visual brand identity that we were going to completely overhaul.
Trying to build the perfect, sustainable system up front wasn’t going to work.
We decided to treat impermanence as intentional strategy. We also wanted to learn how to best use Ditto in a design system.
Three things made this work for us: a minimum viable system that would grow organically. Neutral, semantically-oriented tokens. And ruthlessly pragmatic case-by-case integration.
A minimum viable system that would grow organically
We knew that if we tried to systemize everything up front, we’d spend a lot of time systemizing things that we’d end up replacing or redesigning or leave untouched. We needed just enough design system.
For us, a design system is a higher-level concept that includes the standards and principles for design at scale, including things like the visual design language, typography, colour palettes, components, content style guides, and tooling.
Our mindset was to systemize the right things at the right time. Finding the minimum viable system meant auditing the existing product for the most common types of components and patterns, which would become the core atoms and components. At first, this was things like a basic set of buttons, inputs, and controls.
Then, we created the tooling to give us parallel component libraries in design and development. For standard functionality, we defaulted to wrapping Radix components; we custom-built domain-specific components as needed.
Embracing the minimum viable system meant embracing the reality of design syntropy in design artifacts: each artifact represents a source of truth only in a moment of time, and is expected to drift out of alignment with the reality of the product. Impermanence was a feature.
Neutral, semantically-oriented tokens
We expected the visual brand identity to change significantly in ways we didn’t yet anticipate, which meant we had to be careful about baking in too much of a distinct identity into the underlying usability of the product itself.
This meant creating a relatively neutral set of design tokens—typographic styles, colours, shadows, etc. with a focus on semantics.
This adds a level of abstraction where you might have colour-grey-50 and color-grey-100, mapped to border-primary and border-secondary. We try to use the semantic values everywhere. Then, future changes to the underlying base tokens ought preserve the intended hierarchy, affordances, signals, and overall usability even as the visual identity changes. This effectively makes it “themeable” from the beginning.
Typically, a neutral visual identity isn’t a great idea for a product, because everything else has to work that much harder to make the overall brand identity cohesive and distinct. But as our rebrand and Ditto 2.0 matures, we’ll shift towards a more permanent design system that intentionally brings the new brand language into the product UI, knowing we’ll be able to express that brand without affecting hard-won usability.

Ruthlessly pragmatic case-by-case integration
Trying to implement the design system across the whole product up front would be a waste of time and negative ROI in the long run. But we did need to start using it in Ditto 2.0 to impact our velocity.
When we created net new UIs, we designed and built them using the design system in full.
When we touched an existing workflow or view, we made a case-by-case determination if it would provide lasting value to rebuild the system, or if we should simply build the new functionality with the system.
This meant we had a somewhat blended UI between legacy and new product surfaces, but the intentional neutrality of the new system meant it felt relatively seamless. And we could test and improve on the system for real, without committing to the whole thing up front.
This approach let us do a months-long private, then public, beta, in the real product, alongside the legacy product.
When we eventually needed to refactor the system, it was because the ongoing project work was evolving the system in situ in response to what we were learning, but we intentionally weren’t bringing it back to the system level on a consistent basis.
Using Ditto in your design system
Ditto helps teams to systemize their product copy end-to-end, from draft to deploy. We used our own design system to learn more about what works well when you apply a content system to a design system.
A few key things we learned:
- Your content system in Ditto is another piece of the higher-level design system that includes your component library, typography, colour palettes, and content style guides. It’s not within your Figma component library—it’s its own strategic asset alongside the other building blocks of your design system.
- Linking text in your Figma component library to Ditto pays off the most when you use your component library to represent many different states of complete UI elements—when your component library is a living reference to interfaces in production.
- If your Figma component library is more oriented around atomic components—meaning that the copy in those components is intended to be re-written anywhere it’s used in another Figma file—then Ditto provides the most value when the text in those Figma component instances is linked directly to Ditto text items. Then, anywhere text layers are linked to that text item, they’ll be kept in sync with your source of truth in Ditto.
All systems are inherently ephemeral on a long enough time scale
Design systems are hard. But we made it work for us. Rather than going in thinking of our design system as a permanent source of truth from the start, we built what we needed when we needed it, accepted drift, and focused on what would give us lasting cumulative impact.
As Ditto 2.0 matures, so too will our design system, becoming a more stable source of truth over a longer period of time.
.png)

