Crafting compact design systems

Matt Lambert
6 min readDec 19, 2023


Lego building blocks of a system

Not all design systems are created equal; they should be tailored to meet the specific needs of each organization. The requirements of a startup differ significantly from those of a large company or enterprise. Before embarking on the development of a design system, it is crucial to carefully evaluate the potential benefits.

For startups, the emphasis is often on speed, but it is equally vital to establish scalable code from day one, mitigating the need for extensive rework in the future. On the other hand, enterprises prioritize not only speed but also consistency. In scenarios where multiple products and teams leverage the same system and brand, a unified design system becomes imperative. This consistency is essential to ensure seamless collaboration across various products. Moreover, for enterprises dealing with SaaS products, the design system may need to be sophisticated enough to support theming, addressing the diverse needs of customers effectively.

Understanding how to navigate the pitfalls

Today, let’s turn our focus to company design systems and delve into their pivotal role in fueling startup success. While the immediate benefits for designers revolve around heightened speed and consistency during the design phase, it’s essential to acknowledge the broader advantages for both design and development teams.

Initiating a streamlined system from the outset allows your development team to accelerate its pace and generate higher-quality code, minimizing the need for extensive rework down the road. In the early days of startups, the engineering side often takes a backseat, resulting in disconnected code that varies between features, depending on the engineer responsible.

As the project evolves, typically around the one-year mark, the consequences of this practice become apparent. Instead of focusing on delivering new features swiftly, teams realize they’ve accrued substantial technical debt due to the absence of upfront alignment on components. The pivotal moment arrives when the team must decide whether to address the accumulated debt promptly or brace for persistent challenges, potentially hindering development speed.

The repercussions of neglecting a cohesive design system become evident — developers may move on to other projects, taking invaluable tribal knowledge of the front-end workings with them. The absence of shared code, documentation, or guidelines exacerbates the situation as the product evolves, and extracting code from one feature to use in another becomes a time-consuming task resembling a tangled spiderweb.

As products evolve and design changes are required, lacking a central repository of components turns seemingly straightforward modifications into complex challenges that affect multiple features with disparate implementations. This not only risks the loss of developers but also poses a significant hurdle in adapting to changing requirements efficiently. In essence, the absence of a well-established design system transforms what could be a straightforward process into a convoluted and time-consuming ordeal, potentially hindering the overall development trajectory.

A compact solution

The solution lies in establishing a streamlined component library early in your product’s lifecycle while keeping it compact and lightweight. The objective is to define fundamental branding, tokens, and components necessary for any web app. On the design front, it’s crucial to systematically develop these elements and maintain them as a singular source of truth. Typically, this takes the form of a living documentation platform such as Storybook, providing a dynamic and centralized reference.

A live, operational source of truth is indispensable for components, surpassing mere visibility in Figma. Isolation serves a dual purpose — it provides a centralized hub for testing, documentation, and reference across all stakeholders and becomes an invaluable resource for onboarding new team members as the business expands.

In the early stages of a product, a compact design system makes practical sense. Rapid changes characterize the nascent phases of a product, where branding and design maturity are yet to be fully realized. Designers crave flexibility to make swift adjustments based on user interactions and feedback. A compact system facilitates easier changes without extensive ripple effects, especially when compared to more mature systems.

Exercising self-control is pivotal for designers to prevent system sprawl. Restricting the introduction of variants is essential; for instance, having 1–2 primary and secondary button variants is often more than sufficient. Semantic buttons for specific use cases, coupled with variations in size (small, medium, large), cover the primary needs at the outset. This principle extends beyond buttons — it’s a guideline applicable to all components within your system.

When naming variants, opt for generic terms detached from specific color names. This ensures flexibility to seamlessly incorporate different color tokens down the road, accommodating theming or rebranding initiatives. Designers must exhibit discipline, critically evaluating the business advantage of introducing new elements. If the answer is not a clear affirmative, leveraging the existing components proves more strategic than introducing unnecessary bloat.

What does a compact system need to be successful?

Ever wondered about the anatomy of a compact component design system? It’s a harmonious trio comprising branding, tokens, and components.

Firstly, let’s tackle branding. This involves defining your logo, selecting supporting colors, and determining the typefaces that will embody your product’s visual identity. Once the branding essentials are in place, it’s time to venture into the realm of tokens.

Tokens, the tiniest cogs in the design system machinery, act as fundamental properties akin to CSS class attributes, providing crucial information for each component. Among the key token components are your color palette, featuring primary and secondary color ramps, and semantic colors. Consider publishing these tokens even if you don’t use all of them initially; it’s a strategic move that streamlines future adjustments and additions to your system.

Typography is another vital token. Choose your typeface and establish a typographic scale, aligning it with HTML semantic tags. While the essentials are covered, optional tokens like brand-specific colors, icons, and reusable effects (shadows or borders) can be included as needed.

Tokens are the playground where a broader starting point is acceptable, serving as a comprehensive list of properties for consumption by your component code.

With tokens firmly defined, the next step involves crafting the actual components and leveraging these tokens. A concise component system typically encompasses buttons, form fields, radios, checkboxes, dropdown menus, alert banners, progress bars or loaders, toasts, badges, tabs, links, tooltips, modals, and navigation toolbars — essentially, all the foundational building blocks necessary for your app’s creation.

Can we speed this up using frameworks?

Contemplating the use of an underlying UI framework to expedite your development process? It’s a decision that demands thoughtful, long-term consideration before reaching a verdict.

Engineering teams often lean towards frameworks like Material UI for the apparent time-saving benefits and streamlined theming options. However, this convenience comes with potential pitfalls. For instance, if your system aims to be themeable by customers, selecting a framework that supports this licensing and reselling model is crucial. While it might seem like a shortcut, it introduces ongoing maintenance challenges, requiring support for updates on the chosen framework and the intricate connection to your components.

Lock-in is another drawback of this approach. If a necessary component isn’t part of the chosen framework, your engineers will have to craft it from scratch, resulting in the maintenance of a custom library alongside the Material UI one — adding another layer of complexity.

Personally, I advocate for a more versatile solution — enter Tailwind CSS. Tailwind is an unopinionated utility framework, serving as a foundational platform for implementing your tokens. Whether you need a type scale or any other design token, Tailwind has it covered, allowing you to easily set your preferences. While Tailwind extends beyond a mere shortcut for tokens, exploring its full potential is best left to the developers. The primary advantage lies in its ability to accelerate your progress without overly committing to a specific direction, providing the flexibility you’re bound to need down the road — I guarantee it.