Skip to main content
Anna Schumacher
UI collage of an e-commerce layout showing product cards, content cards and promotional banners for beverage items

Designing for composability at scale

How composable components bridge the gap between our Design System and the evolving needs of our platforms.

Company
Heineken
Timeline
2025
Scope
Customer, distributor & advise platforms
Team
1 Design System Designer (me), 1 Product Designer, 1 Front-end Developer

As eazle's platforms expanded across markets, our Design System needed to evolve from a component library into a scalable architecture.

In 2025, I led a system-level initiative that introduced composability as a core principle. The Product Card became the first large-scale redesign, reshaping how we structure components, distribute ownership and scale across platforms. After a successful implementation, other components like Tiles and Overlays followed.

Image labeled ‘Before’ showing a chat-style request (‘Hey DS, I need this:’) alongside a screenshot of a product card UI, with two response options: ‘Sorry, you can’t’ and ‘We will add it to the system!’.
CHALLENGE
Growth exposed the limits of tightly built components
Our original component set was built quickly to support immediate business needs and worked well at the time. But as the product ecosystem grew, this led to: 👎 Increasing complexity 👎 Structural constraints 👎 Limited scalability 👎 Frequent detachment 👎 Lots of support requests This was especially true for our Product Card, which is the 2nd most used component in our ecosystem. Yet for something so fundamental, it was not designed with system-level scale in mind, so...
How might we create components that allow for greater flexibility for designers and developers to adapt to emerging use cases and ensure the system evolves into an enabler as our platforms grow?
Image labeled ‘Before’ showing multiple product card variants and states (e.g., discounts, out-of-stock, quantity controls) alongside a settings/config panel with toggles for descriptions, price, product labels, and product details like brand, type, and volume.
APPROACH
Trying to fix what was already there would only recreate the same problem in a new shape
So I stepped back, took a more holistic approach and started thinking… 💭 What is a Product Card in our system? 💭 What should the Design System define? 💭 What should be left open by design? Just because it’s not available in the Design System, doesn’t mean it should be impossible to create.  At this point the focus shifted from the Product Card itself to defining a generic Card that enables the composition of Product Cards.
Image  labeled ‘After’ showing a modular product card layout broken into swappable parts—image, title/description, out-of-stock status, price block, and quantity stepper—connected with dashed arrows to illustrate composable components.
SOLUTION
From static to smart: introducing a content-agnostic Card that separates structure from context
To support scalable growth, the way Cards exist in our system was restructured. The core decision was architectural: separating the foundation from the product.
Card, Design System-owned 👉 Content-agnostic 👉 Accessible by default 👉 Flexible within constraints
Product Card, Platform-owned 👉 Layout variations 👉 Business logic 👉 Feature-specific behaviours
Now the Card defines the structure and quality, but makes no assumptions about any product logic.
Image labeled ‘After’ showing a Card component built with slots: dashed placeholders for ‘Visual’ and ‘Content’ in different layouts, alongside a configuration panel with toggles and slot selectors for orientation, visual overlay, top, bottom, and content.
Designed for composition and autonomy: defining less to build more with slots
With the use of flexible slots, each Product Card becomes a composition built on a shared foundation. ✅ Configurable layouts, safely to extend ✅ Endless options through structural building blocks ✅ Composition rules instead of fixed variations ✅ Accessible and performant by default The Design System evolved into an enablement layer that supports teams through structure rather than restriction.
Promotional banner card with a photo on the left and text reading ‘Learn more about our loyalty program’ and ‘Earn bonus points and unlock personal discounts,’ plus a green circular arrow button on the right.
Grid of product cards for beverages showing images, names, pack sizes, reference numbers, prices, and ‘Add to cart’ buttons.
Wide promotional banner with a photo of a smiling delivery driver and the headline ‘You order. We deliver.’ plus supporting text and the eazle logo.
Vertical list layout of product rows showing a thumbnail image, product name and pack size, price, a heart (save) icon, and an ‘Add to cart’ button for each item.
Order summary card labeled ‘Processing’ showing a row of product thumbnails, an order number, order date, total amount, and two buttons: ‘Add to cart’ and ‘View order.’
IMPACT
Fewer support requests
Fewer implementation or maintaining requests as teams are now capable of making changes themselves.
Faster iterations and delivery cycles
Teams ship and test variations independently, shortening iteration cycles and increasing business impact.
Future ready architecture
Platforms can adopt the Card foundation without inheriting other product complexity.
Imag labeled ‘After’ showing a chat-style request (‘Hey DS, I need this:’) with a product card screenshot, and a single response saying, ‘You can create this yourself with our composable component!’.
KEY TAKEAWAYS
Empowering teams requires structural clarity, not fewer rules
Design Systems create the most value when they enable autonomy
Flexibility and consistency are not opposites when structure is intentional