[Meta] Make Drupal the first "design-system native" CMS + Unify & simplify render & theme systems

Created on 30 June 2025, 24 days ago

Problem/Motivation

Lackluster contrib space for themes

This is one of the symptoms of a few problems with Drupal theming:

  • Themes are not sharable, because we are theming a project instead of implementing a design. For example, adding a node--warehouse.html.twig template will be useful only for project with the exact same warehouse content type.
  • If shared, a theme is not "plug and play", for the same reason. There is always a template missing, because of the new config we are building for a project. For example, where is my media--perfume.html.twig?
  • The DX (developer experience) is not friendly. Too much drupalisms. For example, what the heck is taxonomy-term.html.twig? Sometimes, PHP is needed đŸ˜±

Business agnostic coding

Modules don't have those issues because they are business agnostic:

  • no business in PHP code which is exposing swappable, shareable, reusable Drupal plugins
  • all business in config entities (content types, views, contribution workflow, text format, displays...)
  • business (config entity, site building) is calling the code (plugin attachment), not the other way around

Themes need the same logic: provide configurable plugins we can attach to our displays.

So, we need to inverse the workflow by asking the front-dev to implement a design (using Drupal's YAML plugin discoveries) instead of theming a Drupal project. Front-developer is becoming a plugin provider without realizing it:

Thanks to those additional YAML files, Drupal specific but describing only the UI implementation, front-developer is enjoying ownership & empowerment.

So, what would be the plugin types? How can we make the YAML front-dev friendly?

Phase 1, 2025: Add missing theming API

We already have the solution in Drupal Core, because we are already asking the front-dev to implement design system parts with plugins YAML discovery:

Design systems are a design conceived and implemented in a business/project agnostic way. One UI design = many projects/products. So, their philosophy fits with our goal of being sharable between Drupal projects.

We need to complete with missing design system parts:

And improve what we already have:

In order to allow front-developers to implement full, ready to use, designs into a Drupal theme.

This is also impacting the Render API by adding new renderables and render properties which are not describing the CMS application but the design implementation :

Already in Drupal Core:

Proposed for Drupal 11.3 (work in progress, may change):

Phase 2, 2026: Simplifying Render & Form APIs

Those additions will allow us to solve a 10 years old issue : Drupal's render & theme system are too complex to use. See: đŸŒ± Unify & simplify render & theme system: component-based rendering (enables pattern library, style guides, interface previews, client-side re-rendering) Active

This is not the first time adopting design system methodology is expected to help us fixing desperate issue: 🐛 SDC: Make empty render arrays evaluate to false in component templates Active to address đŸŒ± [meta] Themes improperly check renderable arrays when determining visibility Needs work

Current status

Let's not forget the Render API is great:

  • Declarative: Easy to type. (de)Serializable if clean.
  • Easy nesting: The Virtual DOM of Drupal. We are building a tree.
  • Data bubbling: Declare locally, impact globally
  • Asset libraries management: Our beloved libraries.yml
  • Clever caching: Context, tags, keys


Building displays by assembling configurable plugins returning renderables is so nice.

However, the renderables themselves are an issue. They are too many of them and they are of 3 kinds:

  • 35 render elements in Core:
    $ grep -hoEr "#type' => '(\S+)'" core/ --exclude-dir tests | sort | uniq -c | sort -nr
    138 #type' => 'details'
      94 #type' => 'container'
      93 #type' => 'link'
      68 #type' => 'table'
      47 #type' => 'actions'
      36 #type' => 'inline_template'
      27 #type' => 'fieldset'
      23 #type' => 'html_tag'
      21 #type' => 'status_messages'
      14 #type' => 'pager'
      

    
  • 99 theme hooks in Core:
    $ grep -hoEr "#theme' => '(\S+)'" core/ --exclude-dir tests | grep -v "__" | sort | uniq -c | sort -nr
    84 #theme' => 'item_list'
    21 #theme' => 'username'
    16 #theme' => 'image'
      7 #theme' => 'status_messages'
      7 #theme' => 'image_style'
      6 #theme' => 'table'
      6 #theme' => 'links'
      5 #theme' => 'update_version'
      5 #theme' => 'indentation'
      5 #theme' => 'file_upload_help'
      

    
  • 2 special ones:
       1016 '#markup'
           85 '#plain_text'
    

đŸ˜± 135 renderables to learn/use? So confusing and error prone.

95% of renderables can be deprecated

We have SDC for UI components now so:

  • #type => component can replace a lot of hook_theme, the ones describing UI components: breadcrumb, progress_bar, links...
  • We can also replace the 34 render elements which are wrappers around hook_theme (what they do, adding asset libraries, variable typing... is already done by SDC) we removed : table, status_messages, pager...

The hook_theme not suitable for conversion to SDC are often annoying CMS-related wrappers we can get rid of anyway : block, node, view, field


The few remaining render elements can't be expressed as UI components:

  • some must be kept because they represent other design systems artefacts (icons...) or low level tools (HTML elements, placeholders...)
  • some may (not found in my today look) be shortcut to Drupal callables returning renderables, it is better to explicitly call the callable (service, function, method..) instead

Deprecation of many Twig additions

Also, it may be the opportunity to challenge the various additions Drupal made to Twig last 10 years.

Most of the Drupal-specific Twig functions added in 2015, during the development of Drupal 8.0, are requesting the Drupal application state:

Other functions have their own kind of issues:

Some filters have similar issues (|render(), |add_suggestion()...)

Those functions were great and pragmatic when they were implemented 10 years ago, they made the conversion from PHP Templates (using functions like theme_link()) to Twig easier and the community-wide transition a success.

However, they may not fit with the new, design-system oriented, paradigm started with SDC, where the UI component needs to encapsulate business-agnostic UI-logic only and stays "dumb" & stateless. On any website, any context, with the same values injected in slots & props, always return the same markup.

We can dream in a future situation where only 5 additions will stay relevant:

  • the PrintNode visitor to send all printed variable to the renderer service. That's the core of Drupal Twig rendering, it works very well and must be kept.
  • Attribute object and the related create_attribute() function, but let's hope we will be able to get rid of it someday: ✹ HTML attributes as Twig mappings instead of PHP obejcts Active
  • add_class() & set_attribute() filters, they make sense used with the SDC slots.
  • the new icon() function for the Icon API. It follows Twig philosophy of using functions to generate printable data
  • the translations helpers (t function, trans tag). Important feature for a CMS. Why not proposing this to upstream Twig?

Deprecation of ThemeManager::render()

Because SDC is not passing through the ThemeManager, if we reach a situaton where all template-based renderables are managed by SDC, we don't need the template loading feature of the ThemeManager anymore.

So we get rid of it and its related mechanisms:

  • Theme wrappers: Confusing and useless. You can always use an upper level instead.
  • Templates suggestions: Not discoverable. Messy. Blur the business / view separation.
  • Preprocess hooks: Risky. Unfriendly. Blur the business / view separation. Unpredictable order of execution.

@catch is alerting us about the complexity of this ambitious task:

The projects might not be using them directly, but there are dozens/hundreds of preprocess hooks running on those projects via core and contrib modules. https://api.drupal.org/api/drupal/core%21modules%21node%21node.module/fu... is a monster just by itself. edit: or https://api.drupal.org/api/drupal/core%21modules%21system%21system.admin...

Removing just one variable is non-trivial, although at least we have deprecation support now.

Conclusion

We can have equally useful Render & Form APIs with less than 15 renderables:

  • Design systems artefacts:
    • #type => component: for UI components, including form elements once 📌 Define form elements from SDC Active is done
    • #type => icon: for icons
  • Lower level tools:
    • #type => inline_template
    • #type => html_tag : for HTML elements
    • #type => link
    • #markup
    • #plain_text
    • #lazy_builder
  • Non-UI form elements: #type => submit, #type => value, #type => item...

And a few, maybe less than 15 too, "shared" render properties:

  • For render processing: #attached, #cache...
  • Related to design systems (WIP proposals): #styles, #tokens, #mode...
  • For form elements processing: #name, #default_value, #required...

And now we have an purely design/UI based Render API!

If we do that, step by step, deprecating slowly, not breaking anything, the display building tools from Core and Contrib will have a simpler implementation and will have an easier time introducing new features.

User interface changes

No

Introduced terminology

Sometimes, see specific issues.

API changes

Yes, we deprecate a lot of things.

đŸŒ± Plan
Status

Active

Version

11.0 đŸ”„

Component

theme system

Created by

đŸ‡«đŸ‡·France pdureau Paris

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @pdureau
  • đŸ‡«đŸ‡·France pdureau Paris
  • đŸ‡«đŸ‡·France pdureau Paris
  • đŸ‡«đŸ‡·France pdureau Paris
  • 🇹🇭Switzerland 4aficiona2

    Great if Drupal (finally) goes this way and has ambitous goals in being a "Design System first" CMS.

    Maybe more "niche" stuff in the future (animations/transitions, (buildtime) design tokens...)

    This is in my opinion an absolute must and basis to have a Design Token API if we want to call Drupal a "Design System first" CMS. Design Tokens fuel everything and are the most "atomic" design decisions — especially if they are also system/language/type agnostic.

    There are quite good tools out there like https://styledictionary.com/ to also transpile/convert them to the wished format and having "CSS variables / custom properties / runtime tokens" availabe is absolute necessary.

    Imo Design Tokens are a corner stone of a "Design System first" CMS :)

  • 🇬🇧United Kingdom catch

    Overall this looks great to me, there are thing that seem very obvious and others that aren't as clear, but I am not a design systems person so I'm really just looking at it for what the concrete changes for existing things would be.

    I think it would be useful to try the theme/render -> SDC path for one (non-form) element so that we can hopefully flush out what the issues are with conversions, deprecation etc.

    For me an example which you would think would be simple but unfortunately is not, is item_list. We already have multiple issues open trying to clean that up going back to at least 2008:

    📌 Replace links.html.twig with item-list--links.html.twig Needs work
    ✹ Replace .info.yml with composer.json for extensions Postponed
    📌 Remove title and wrapper div from item-list.html.twig Needs work
    #2032695: Use item-list.html.twig instead of views_view_summary.html.twig →

    Non-exhaustive list of questions for me would be things like:

    1. What does the new SDC for item lists look like?
    2. What is the relationship between this and the replacement for #theme => links?
    3. Can the duplicate views template just use the item_list SDC or does views need its own version for some reason?
    4. What happens with existing uses of item_list that switch to the SDC but which are relying on theme suggestions.

    If we go through this for one element/theme function (including the duplicates and near duplicates and the usages) from start to finish, then it would hopefully make it easier to go through the process for all the other ones.

  • đŸ‡«đŸ‡·France pdureau Paris

    Hi @4aficiona2

    That's great to see another design system lover here 👍

    This is in my opinion an absolute must and basis to have a Design Token API if we want to call Drupal a "Design System first" CMS. Design Tokens fuel everything and are the most "atomic" design decisions — especially if they are also system/language/type agnostic.

    I agree (buildtime) Design Tokens have a central part in design system methodology. I called them "niche" in the issue description because the goal here is to make Drupal able to use an already built design system implementation.

    "Working with a design system" as a different meaning according to the persona and the step:

    1. As a designer, I am designing the system, and I set variables in my design tools to organize my work. Some of those variables can be shared as design tokens.
    2. As a front-developer, I am implementing the design system, and I set variables in my CSS preprocessor (so, as Saas variables, Less Variables, Tailwind's @apply directives...). Those variables could also be considered as design tokens, retrieved from the ones shared by the designer. They are resolved at build.
    3. As a back-developer or site builder, I am using the design system, managing my Drupal displays using what was built by the front-developers from the (buildtime) design tokens:
      • UI components
      • Icon packs
      • style utilities (in Tailwind, by design, each style option is also a design token but that's not the case in other design systems I have studied)
      • CSS variables (which are an subset of the design tokens which are overridable at runtime)
      • ...

    The current issue is not for implementing a design system, but for using it. So, it is focused on the back-developer and site builder personas, to let them use the stuff built by the front-dev from design tokens, shipped i na Druapl theme, rendered by the browser. So, I don't see how the design tokens, which have already "disappeared" at this step, are fitting.

    Visual workflow:

    Anyway, I am not closing the door here. There may be something to do at the "using a design system" step, if I follow the hopes of some brilliant Drupalers:

    There are quite good tools out there like https://styledictionary.com/ to also transpile/convert them to the wished format and having "CSS variables / custom properties / runtime tokens" available is absolute necessary.

    This tools looks great, it can be useful for the front-devs which want to expose some of the design tokens as CSS variables. It is a design system implementation decision.

    To build our Drupal displays, why not using directly the CSS variables? So, we benefit from 2 strategic decisions made by the front-dev who:

    • have already picked the tokens to expose at runtime, instead of struggling with myriad of obscure tokens
    • set the default values according to the scopes ("scope" mechanism are not a thing with design tokens, it must be added at build time)
  • đŸ‡«đŸ‡·France pdureau Paris

    Hi Catch,

    Here is a spontaneous, quickly written, answer to start the conversation. I guess I will have the opportunity to refine my analysis later.

    I think it would be useful to try the theme/render -> SDC path for one (non-form) element so that we can hopefully flush out
    For me an example which you would think would be simple but unfortunately is not, is item_list. We already have multiple issues open trying to clean that up going back to at least 2008

    You are right, item_list is not a simple example but an interesting one.

    item_list is a template declared by Drupal\Core\Theme\ThemeCommonElements:

    'items' => [],
    'title' => '',
    'list_type' => 'ul',
    'wrapper_attributes' => [],
    'attributes' => [],
    'empty' => NULL,
    'context' => [],
    

    with this template from system module:

    {% if context.list_style %}
      {%- set attributes = attributes.addClass('item-list__' ~ context.list_style) %}
    {% endif %}
    {% if items or empty %}
      {%- if title is not empty -%}
        <h3>{{ title }}</h3>
      {%- endif -%}
    
      {%- if items -%}
        <{{ list_type }}{{ attributes }}>
          {%- for item in items -%}
            <li{{ item.attributes }}>{{ item.value }}</li>
          {%- endfor -%}
        </{{ list_type }}>
      {%- else -%}
        {{- empty -}}
      {%- endif -%}
    {%- endif %}
    

    Used 81 times in Drupal Core:

    $ grep -r theme.*item_list web/core/ | grep -v test | grep -v html.twig | wc -l
    81
    
    1. What does the new SDC for item lists look like?
    2. What is the relationship between this and the replacement for #theme => links?
    3. Can the duplicate views template just use the item_list SDC or does views need its own version for some reason?
    4. What happens with existing uses of item_list that switch to the SDC but which are relying on theme suggestions.

    Let's try a protocol. Is it a candidate to conversion to SDC?

    • Is it something we can talk with a designer and document in a design system? Kind of, but a bit generic purpose
    • Is there some specific markup? No, except the 'item-list__' ~ context.list_style class. Specific attributes are added from the render array only 3 times: WorkspaceListBuilder, PluginBase, FieldStorageReuseForm. SO it is marginal.
    • Is there a good reason to override it for a theme to push its own rendering? Seems silly, it is use more than a generic rendering tool and overriding its look may break stuff. That's why the only preprocesses and template overrides are targeting its template suggestions: item-list--search-results.html.twig and item-list--media-library-add-form-media-list.html.twig

    So, it may not a be a good candidate for SDC. At the difference of some renderables also defined in Drupal\Core\Theme\ThemeCommonElements which will shine as SDC: progress_bar, feed_icon, status_message, pager...

    So, what do we do with item_list? Maybe we can add it to other toolset of template-free render elements, alongside html_tag, link, inline_template, value, submit... Let's try to keep this list as compact as possible, but for a renderable used that much with those characteristics, it may be relevant. It will also be the possibility to add the logic from theme.inc's template_preprocess_item_list if necessary.

    If we go through this for one element/theme function (including the duplicates and near duplicates and the usages) from start to finish, then it would hopefully make it easier to go through the process for all the other ones.

    As said before, item_list's theme suggestion's are the target of all the preprocess and overrides:

    $ grep -r _preprocess_item_list web/core/ | grep -v html.twig | grep -v test
    web/core/themes/claro/claro.theme: * Implements hook_preprocess_item_list__media_library_add_form_media_list().
    web/core/themes/claro/claro.theme:function claro_preprocess_item_list__media_library_add_form_media_list(array &$variables): void {
    web/core/themes/olivero/olivero.theme: * Implements hook_preprocess_item_list__search_results().
    web/core/themes/olivero/olivero.theme:function olivero_preprocess_item_list__search_results(&$variables): void {
    web/core/themes/stable9/stable9.theme: * Implements hook_preprocess_item_list__search_results().
    web/core/themes/stable9/stable9.theme:function stable9_preprocess_item_list__search_results(&$variables): void {
    web/core/includes/theme.inc:function template_preprocess_item_list(&$variables): void {

    So, maybe let's study the SDC conversion of item-list--search-results.html.twig instead. I will update my comment tomorrow, following your questions and the proposed protocol.

  • đŸ‡©đŸ‡ȘGermany D34dMan Hamburg

    @pdureau,

    Phew, thats a lot of things. I agree with most parts. Maybe devil is in the details. Following feedback serves to complement the scope that has already been discussed.

    Feedback A: We need to establish a common understand of what Design System means in Drupal Community
    Even experienced developers can struggle with this concept. We need to start by documenting what "Design System" means, how it relates to Component/Component Library, Templates and Theme. What it means for various stakeholders like Designers, Site Builders, Frontend Dev, Backend Dev, Core / Contrib Module maintainers and so on. This way, after having a shared understanding, we can talk about implementation details. Without this, am afraid, its too much at stake.

    Let me try to establish a glossary, on which am going to respond to this issue.

    Drupal Agnostic

    - Design System : In a nutshell "style guide + components + interaction + code + tooling + governance"
    - Design Token : "Glue" that holds design system, Style guide and component library together.
    - Style Guide : Visual rules
    - Component Library : Collection of re-usable UI Elements.
    - Design Tool : A design tool is a tool for visual design creation and editing (Figma, Photoshop, Illustrator)
    - Translation Tool : Design token translation tools translate token data from one format to another (Style Dictionary, Terrazzo, Human!!! )

    Drupal Specific

    - Single Directory Component: a way to expose a component in component library to Drupal

    The way things are layered in my mind (this layers could be arranged differently in other team/organization as its not normative). The further down you go, the more specific and opinionated the implementation becomes.

    - Style Guide: Tokens represent brand rules
    - Design System: Tokens are foundation that defines design primitives
    - Component Library: Component "consumes" tokens for consistent styling
    - Themes : Drupal themes are not aware of Design System. Drupal themes provides an API to collect various components that contribute to layouting and styles.

    Feedback B: Request to broaden the scope of approach (nitpick)

    The approach here seems to explore on the existing integration. We have exposed "Component library" to Drupal via SDC. So lets assume Component as single source of truth to implement Design system. Which is already a win for Team who have full control on the component library. No doubt.

    This requires,
    - Prequisite A: The component library and Design system ends up having 1:1 relationship
    - Prequisite B: All components/templates in Drupal needs to be replaced with Design System specific Component.

    By broadening the scope, I am requesting to bring Design Token as first class citizen into Drupal. This means
    we are using the same "glue" that keeps styleguide, design sytem and component library in sync, in Drupal as well.

    How can we achive this?

    - An API to register Design Tokens in Drupal
    - An API to reference Design Token from another Design Token
    - An API to consume Design Token during run-time

    Let me explain what this means using some examples:

    Example:

    Status message in Drupal.

    Consider a future that Drupal Core ships with a component for status message.
    It exposes following "component level" Design Tokens.
    This way component is not opinionated about what exact colors are used. It may ship with sensible defaults.

    - core.status_message.color.success.bg
    - core.status_message.color.success.content
    - core.status_message.color.error.bg
    - core.status_message.color.error.content
    - core.status_message.color.warning.bg
    - core.status_message.color.warning.content

    Now since Drupal knows about Design Tokens exposed by components, We can provide an interface
    at "Theme" level for Site builders to map it to Theme level Tokens.

    Example Mapping.

    status_message.color.success.bg      : "{{ my_design_system.color.success.bg }} 
    status_message.color.success.content : "{{ my_design_system.color.success.content }} 
    status_message.color.error.bg        : "{{ my_design_system.color.error.bg }} 
    status_message.color.error.content   : "{{ my_design_system.color.error.content }} 
    status_message.color.warning.bg      : "{{ my_design_system.color.warning.bg }} 
    status_message.color.warning.content : "{{ my_design_system.color.warning.content }} 
    

    What did we achieve with this arrangement?

    - Core's "status component" doesn't know about "my_design_system"
    - But since its exposes Design token, it allows us to create a UI for overriding the value (in Drupal Theme).
    - The Status message can be shown in colors matching "my_design_system"

    Why is this important?

    - This allows us to generate components which are agnostic of design systems, and yet provide a way to adhere to it.
    - Is this perfect fit for all scenarios? NO, it is not.

    Feedback C: Drupal Core can choose an opinionated way to implement design token

    The Core (and contrib to follow by example set in core), can ship with an opnionated design token implementation. I recommend CSS Variables for implementation and Material Design (M3) for token hierarchy and naming convention (https://m3.material.io/foundations/design-tokens/overview).

  • đŸ‡«đŸ‡·France pdureau Paris

    Hi Shibin. Nice to have you here. Thanks for this deep and interesting feedback.

    Feedback A: We need to establish a common understand of what Design System means in Drupal Community
    Even experienced developers can struggle with this concept. We need to start by documenting what "Design System" means.
    (...)
    Design System : In a nutshell "style guide + components + interaction + code + tooling + governance"

    There are many definitions available of "design system", but most of them tell the same story: "A design conceived, implemented and governed in a business/project agnostic way. One design = many products.". So it will not be hard to agree on a definition.

    But the real questions is: what do you put inside?

    My proposal:

    • Because Drupal is not a designer tool, let's focus on the "Web implementation" part of the definition.
    • Because Drupal is not a front-dev toolset, let's focus on what we have after the build, when the implementation is already available for use. In other words, when

    So, from this point of view, which part of a design system do we need to address? Let's take an humble and empiric approach of what a already built Web design system can offer:

    • they sometimes have UI components
    • they sometimes have grid & layout systems
    • they sometimes have icons, grouped by packs
    • they sometimes have utility classes
    • they sometimes have custom properties (CSS variables)
    • they sometimes have animations & transitions mechanisms
    • and so on... there is always something to discover

    Feedback B: Request to broaden the scope of approach (nitpick)
    (...)
    Example: Status message in Drupal.
    (...)
    This allows us to generate components which are agnostic of design systems, and yet provide a way to adhere to it.

    An application-side, contextful, stateful, renderable which can be moved around and plugged to / rendered as a UI component? So, a Drupal block plugin?

    Feedback C: Drupal Core can choose an opinionated way to implement design token

    The Core (and contrib to follow by example set in core), can ship with an opinionated design token implementation. I recommend CSS Variables for implementation and Material Design (M3) for token hierarchy and naming convention (https://m3.material.io/foundations/design-tokens/overview).

    "naming conventions", that is something careful about in my opinion. We need to provide a way to describe an existing design system's Web implementation so it can be used in the CMS. But let's avoid telling designers and front-developers how to conceive and implement the design system.

    Because they will not make design systems for Drupal, they already made a design systems for a brand or an organization, and we want to be able to use it in Drupal.

    Today, in Drupal:

    1. We already provide breakpoints.yml but we don' tell which are the breakpoints
    2. We already provide SDC but we don't force some components
    3. We already provide the icon API but we don't tell which are the icons, or how they must be stored, or named.

    Let's continue this way with the new formats we will introduce; and prevent ourselves to push predefined tokens, or predefined components, or predefined anything. We did this mistake once with the current templating we want to get rid off (node--my-business-stuff.html.twig). Let's keep an unidirectional flow, from them to us.

    The stuff we will enforce, it will never perfectly fit the designer and front-dev needs anyway. They will annoy them and may scare them away.

  • 🇹🇭Switzerland 4aficiona2

    Thanks, for your inputs and elaborations @d34dman and @pdureau

    I would love to see that Design Tokens get first class citizens in Drupal. I though have a slightly different definition of what Design Tokens are. I once quoted/defined them here (while working on the Design System for the Swiss Federal Railways / SBB) – aligned with the team who was working on the system – as:

    Design Tokens are design primitives. They contain actual values — design decisions — but can also be accompanied by metadata. Design Tokens are delivered through the Design (Token) API.

    Technically speaking: Design Tokens are organized lists of key-value pairs that describe design decisions, Cristiano Rastelli

    The project is archived and evoled mainly into these two projects (lyne-components, lyne-design-tokens) due to a lack of DS governance — difficulties with management / rejection / budget ... all I can say is: Design Systems can be were tricky since alot of people (from many departements and roles can be involved). Design System definitions vary alot and a Drupal issue page is probably not the ideal way to define/iterate on a vocabulary since only few people interact here and it needs a wider audience/participation since many roles will once be involved/using the Design System.

    If I could wish I'd say ... If Drupal, with its enterprise potential and capabilities (e.g. multisite setups), aims to be a "Design System first" CMS I'd love to see how it address the "System of Systems" approach of Design Systems and implied how it handles Design Tokens (simple/composite tokens, primitive/global tokens, semantic tokens, component Tokens).

    And what is the current state "the new design system for experience builder and drupal cms" → ? I guess they've been doing some work around this topic too.

  • đŸ‡©đŸ‡ȘGermany D34dMan Hamburg

    @4aficiona2, you are my man!

    TLDR; "System of Systems" is what basically it is.
    The one that is near and dear to me is , "Turn Key rebrand opportunity" with what we do.

    Long version:

    Without a clear and opinionated approach to implementing design tokens in Drupal, I doubt there would be any benefit in real-world usage.

    I wanted to share a few thoughts based on discussions I've had around design tokens, especially with designers.

    Drupal as a Project have more than 1 design system

    One thing that often gets missed is that Drupal might need to support more than one design system at the same time. Many designers tend to think in terms of a single, centralized system, but that’s not always realistic for Drupal, where backend and frontend themes can overlap.

    Design Token Name inconsistency

    Also, designers often come from a background where tokens are a newer concept, evolving from static choices like colors and spacing into reusable variables in tools like Figma. Design tokens, as defined in the W3C DTC specification, leave naming and structure open to interpretation. That flexibility is useful, but it can also lead to inconsistencies. For example, changing a token name can cause a breaking change across both design tools and code if not managed carefully.

    In practice, naming conventions and token hierarchy really matter. Mature design systems like Material Design tend to define their own token structure to avoid these kinds of issues.

    Use case where Admin components are shown in Frontend Theme

    Another real challenge I’ve seen is when admin UI components show up in the frontend theme, such as media library, contextual links, or the admin toolbar. These components often bring their own CSS or conflict visually with the frontend theme. When that happens, they don't necessarily need to look perfect, but it would help a lot if they didn’t look broken.

    This is where component-level design tokens can really help, especially if we expose spacing, font, and border as configurable tokens. That would allow site builders to assign values to these tokens in their themes and ensure better visual consistency with minimal effort.

    In this way, design tokens act as local style variables declared by components and defined by themes. It’s a simple but powerful way to align design, admin UI, and frontend themes.

  • đŸ‡©đŸ‡ȘGermany D34dMan Hamburg

    @pdureau, thanks for the invite :) And sorry I got carried away and didn't end my comment.

    My follow up question is, Is this meta discussion's focus on getting Design System into Drupal or is this issue about getting Styles API in, which would allow component to expose some behaviors without implementing props?

  • 🇬🇧United Kingdom catch

    It seems to be used mainly as a shortcut to avoid nesting 2 or 3 html_tag renderables and may not a be a good candidate for SD
    [...]

    It's not a shortcut as such, because we didn't have html_tag until fairly recently, and couldn't nest html tag elementswithin html tags until 2018 and #2694535: Support rect property and nested render arrays in html_tag for dynamic SVGs → . So retrospectively it's a shortcut, but it precedes 'html_tag' by a decade or more.

    So, what do we do with item_list? Maybe we can add it to other toolset of template-free render elements, alongside html_tag, link, inline_template, value, submit

    I think this is reasonable, apart from removing the header, it would mean just not deprecating it in favour of an SDC for now, and we know we have a long list ahead of us before we'd get to it anyway.

    This leaves me with more questions though:

    - If #type item_list stays, what happens to #theme links?

    - do we need to apply a similar analysis to other compound/composite HTML elements (not sure if there is a generic term of these) - I can mainly think of tables and the picture element that are somewhat similar in that there's a complex but mostly predictable HTML structure.

  • đŸ‡«đŸ‡·France pdureau Paris

    I would love to see that Design Tokens get first class citizens in Drupal. I though have a slightly different definition of what Design Tokens are.

    @4aficiona2: It seems we have the same definition of what Design Tokens are. And we agree they are very important in a design system. We are just debating on how to use them in Drupal, or not.

    In practice, naming conventions and token hierarchy really matter. Mature design systems like Material Design tend to define their own token structure to avoid these kinds of issues.

    Yes, every design system has its own vision, intention, constraints, and token structure... So, we need a way of plugging Material Design, or any other Web design systems, to Drupal. Not to take the Material Design structure and naming convention and push it to

    There are quite some good resources around this topic ;)

    Thanks @4aficiona2 for those interesting resources. I am discovering some of them. However, it seems they address mostly the upstream of Drupal theming, don't they?

    Is this meta discussion's focus on getting Design System into Drupal or is this issue about getting Styles API in, which would allow component to expose some behaviors without implementing props?

    @d34dman: We have dedicated issues for ✹ Add a style utility API Active and ✹ Add a CSS variables API Active The current issue is for the bigger scope about design systems API and how they can transform Theme and Render APIs.

    If the discussion about tokens is challenging only one of those 2 dedicated issue, let's move it there. If the discussion has a wider impact, let's keep it here.

    Design Tokens: practical work

    @4aficiona2 @d34dman: Can we agree on those 3 principles before going forward?

    • Instead of targeting a “one-size-fits-nearly-all” design system for Drupal, let's create tools to package any Web design system in a Drupal theme. “Bring your own design system”. We don’t tell upstream how to do their design system, we just help them to plug their own, from public and private projects, already implemented and built, in Drupal.
    • To achieve that, we describe parts of a design system implementation (components, icons, other stuff...) with declarative files in a sharable Drupal theme (so, under the ownership of the front-dev). So we need to add missing YAML formats.
    • Once loaded, those files are augmenting or altering the Render API and other Drupal APIs

    So, about the design tokens. Let's say we load https://tr.designtokens.org/format/ files from a Drupal theme. Example:

    shadow-token:
      "$type": shadow
      "$value":
        color: "#00000080"
        offsetX:
          value: 0.5
          unit: rem
        offsetY:
          value: 0.5
          unit: rem
        blur:
          value: 1.5
          unit: rem
        spread:
          value: 0
          unit: rem
    font-size:
      "$value":
        value: 3
        unit: rem
      "$type": dimension
    
    • what is happening next in Drupal? how do we use them with the Render API (render elements, render properties..) ? what could we do from admin UI?
    • how do we know which ones can be used as class utilities? and which ones are mutually exclusive (an important rule for class utilities)? Is it replacing ✹ Add a style utility API Active ?
    • how do we know which ones can be used as custom properties ("CSS variables")? and how do we manage scoped default values (an important mechanism from CSS variables)? Is it replacing ✹ Add a CSS variables API Active ?
    • do we generate the CSS dynamically from those tokens (with which rules?) or do we rely on the CSS already built by the front dev?

    @4aficiona2 @d34dman: Can we agree on those 3 principles before going forward?

    • Instead of targeting a “one-size-fits-nearly-all” design system for Drupal, let's create tools to package any Web design system in a Drupal theme. “Bring your own design system”. We don’t tell upstream how to do their design system, we just help them to plug their own, from public and private projects, already implemented and built, in Drupal.
    • To achieve that, we describe parts of a design system implementation (components, icons, other stuff...) with declarative files in a sharable Drupal theme (so, under the ownership of the front-dev). So we need to add missing YAML formats.
    • Once loaded, those files are augmenting or altering the Render API and other Drupal APIs

    So, about the design tokens. Let's say we load https://tr.designtokens.org/format/ files from a Drupal theme. Example:

    shadow-token:
      "$type": shadow
      "$value":
        color: "#00000080"
        offsetX:
          value: 0.5
          unit: rem
        offsetY:
          value: 0.5
          unit: rem
        blur:
          value: 1.5
          unit: rem
        spread:
          value: 0
          unit: rem
    font-size:
      "$value":
        value: 3
        unit: rem
      "$type": dimension
    
    • what is happening next in Drupal? how do we use them with the Render API (render elements, render properties..) ? what could we do from admin UI?
    • how do we know which ones can be used as class utilities? and which ones are mutually exclusive (an important rule for class utilities)? Is it replacing ✹ Add a style utility API Active ?
    • how do we know which ones can be used as custom properties ("CSS variables")? and how do we manage scoped default values (an important mechanism from CSS variables)? Is it replacing ✹ Add a CSS variables API Active ?
    • do we generate the CSS dynamically from those tokens (with which rules?) or do we rely on the CSS already built by the front dev?
  • đŸ‡©đŸ‡ȘGermany D34dMan Hamburg

    @pdureau,

    About foundational principles

    Instead of targeting a “one-size-fits-nearly-all” design system for Drupal, let's create tools to package any Web design system in a Drupal theme. “Bring your own design system”. We don’t tell upstream how to do their design system, we just help them to plug their own, from public and private projects, already implemented and built, in Drupal.

    Agree for most part. Suggested change as follows,

    Instead of targeting a “one-size-fits-nearly-all” design system for Drupal, let's create tools to package any Web design system in a Drupal theme. “Bring your own design system”. We are not opinionated about design system, we just help them to plug their own, from public and private projects, already implemented and built, in Drupal.

    To achieve that, we describe parts of a design system implementation (components, icons, other stuff...) with declarative files in a sharable Drupal theme (so, under the ownership of the front-dev). So we need to add missing YAML formats.

    Agree

    Once loaded, those files are augmenting or altering the Render API and other Drupal APIs

    Agree.

    About Normative and Non-Normative Parts
    When it comes to "normative" part, you can see, we already agree.

    I am happy to split the non-normative requests from my side into other tickets if needed, these are

    1. Have a framework of how Design System is implemented and used in Core. This would influence how we ship components in core.
    2. We need to address the challenge that multiple design system is able to co-exists within a single Drupal instance
    3. I see a future where Design Tools and Drupal is tightly integrated. But that is out-of-scope of Core and can be achieved in Contrib or in Private.

    Q&A

    what is happening next in Drupal? how do we use them with the Render API (render elements, render properties..) ? what could we do from admin UI?

    Assumption:
    - All templates in Drupal are using SDC Components which have exposed their Design Tokens
    - Lets call Tokens from the file inside Theme "Theme Design Tokens"
    - Lets call Design Tokens used in SDC Components as "Component Design Token"
    - Lets call Design Tokens declared by Core as "Core Design Token" (This is a Non normative suggestion from my part).

    So a Site builder would be able to,

    - In Theme specific Admin UI, we can now map "Component design Tokens" with the relevant "Theme Design Tokens"
    - NOTE: A theme developer can also ship the mapping right inside the json file.

    In case the mapping is absent,
    - The SDC Component would use the default it ships with
    - This default could be a hard coded value or a reference to "Core Design Token". (If core doesn't ship any tokens, then the components would be shipping default values which are hard coded. Leading to what i would like to call as 50 shades of gray problem).

    how do we know which ones can be used as class utilities? and which ones are mutually exclusive (an important rule for class utilities)? Is it replacing #3517033: Add a style utility API?

    The components must ship with name-spaced design token. The value of such tokes can be hard coded value OR references. A non-normative suggestion from my part is that, if we ship "Core Design Tokens" then core and contrib modules can reference them, without inventing their own values.

    Another advantage is, if all components in core and contrib references "Core Design Tokens", then in theme we might have to only map "Core Design Tokens" to the "Theme Design Tokens" to make all components work more or less out of the box.

    Is it replacing #3517033: Add a style utility API?
    My understanding is, it is not replacing style api which solves a different problem space. However, this would enhance the Styles Utility API by giving it a choice to store references (via design token), rather than design decision.

    Focus of Design Tokens is on how styles are applied across all components. Styles API could reference design tokens, but the way the tokens are collected and presented to users is out of scope of Design Token.

    Example, you can have 100s of colors defined in Design Token... however for background for certain component, you may only expose a sub-set of the colors. Am not sure if its in the scope of styles api to ship compound styles, as background is usually accompanied by an opinionated color for content for accessibility reasons. But I digress.

    Lets say Styles api references a "Core Design Token" "core.color.primary.bg". Then the mapping of "core.color.primary.bg" to "Theme Design Token" would be mapped as described earlier. Interesting, this also means, complex Dark/Light Mode variation can also be supported without Styles API's knowledge.

    For this to be practical, we need to have a way to not only declare Design Token, but also consume them as well.

    how do we know which ones can be used as custom properties ("CSS variables")? and how do we manage scoped default values (an important mechanism from CSS variables)? Is it replacing #3531854: Add a CSS variables API?

    Just like Styles API, this would only enhance the foundation of CSS Variables API. Design Token doesn't bother how you implement things. CSS variable being most convenient and popular one out there, it make sense to introduce support for that first.

    For both Styles API and CSS Variables API, Design Token would provide the framework to reference a normalized entity.

    We have two cases:

    1. If a component is shipping with namespaced design tokens, then theme can target them specifically, and assign values to them.
    2. If a component doesn't ship with namespaced tokens (e.g. it uses "Core Design Tokens"), it will be at mercy of theme's generic mapping.

    do we generate the CSS dynamically from those tokens (with which rules?) or do we rely on the CSS already built by the front dev?

    This depends on how Theme (Themers) want to consume Design Token. I classify it into following categories.

    1. Build Time (outside Drupal's knowledge) : Use same DTCG file as source of Truth, StyleDictionary as Transformer.
    2. In Twig Templates : Consume via various utilities "yet to be provided"
    2.1. Convert a single token into "Class" (e.g. Tailwind utility class or bring your own mapper)
    2.2. Convert a single token to Value (e.g. print "core.color.primary.bg" as #123452)
    3. Convert all available token to Value (Dynamic CSS Generation), example useful with point #1 where you want to inject scoped CSS variables and generate a css file.

    The choice would be with the Theme Developer on how much control they want to have. Point 1 is full control, and Point 2 and 3 goes in the direction to let Site-builder decide the mapping. Also Point 2 and 3 are not a requirement, but a possibility available if Drupal knows about design token. Could go a long way to establish my goal of connecting Design Tool with Drupal.

  • đŸ‡«đŸ‡·France pdureau Paris

    Hi @d34dman we agree on 3 foundational principles and you believe such a Design Token API is not replacing but enhancing the Style API & Variables API proposals.

    If this position is shared by @4aficiona2, I will create an "Add a design tokens API" issue, alongside ✹ Add a style utility API Active & [ #3531854] , and add @e0ipso & @penyaskito to the loop because of their work on https://www.drupal.org/project/design_tokens →

    We will move our discussion there.

  • đŸ‡©đŸ‡ȘGermany D34dMan Hamburg

    @pdureau,

    I will create an "Add a design tokens API"

    Yes. Since we have an agreement on principles, I could review the proposal discussed in the issue description w.r.t. that.

  • đŸ‡«đŸ‡·France pdureau Paris

    Ok, I create the new Core issue this weekend.

  • đŸ‡«đŸ‡·France pdureau Paris

    ✹ Add a CSS variables API Active has been updated. Discussions about design tokens are moving there.

Production build 0.71.5 2024