DrupalCon

The state of JavaScript Code Components in Drupal Canvas

51:10 · 23 Mar 2026 – 26 Mar 2026 · YouTube

About this talk

In this talk, Ban Clei introduces Drupal Canvas, a visual page builder for the Drupal CMS that facilitates component-based UI development. He discusses the three component sources that are integrated into Canvas: single directory components, blocks, and the newly introduced JavaScript code components, which are optimized for a better developer experience. The speaker emphasizes the importance of providing excellent JavaScript tooling both for developers and coding agents, enabling them to work seamlessly in local development environments as well as in Canvas. The talk covers local codebase scaffolding, real-time code editing capabilities within Drupal, and the integration of agentic skills that enhance the coding experience. Ban also presents the Canvas workbench, a tool for local component development that aims to replace Storybook, along with the upcoming features that support server-side rendering and third-party package management. Overall, he highlights the evolution of UI development workflows in Drupal and the potential for decoupling front-end systems to improve usability.

Full transcript

Welcome everyone. My name is Ban Clei. I work at Aquia. Uh I've been in Aqua's Drupal Canvas team since 2024 August. And it's funny that the person who hired me sits right here. And this is the first time I'm I'm meeting him in person. So, hi Ken. Uh good to see you. And um I am the technical lead of uh the code components, JavaScript code components in

Drupal Canvas. And if you haven't really played with Canvas before, it's really not too late to start. It's totally fine. But just a quick intro to Canvas. It's Drupal's new visual page builder and it ships by default with Drupal CMS 2. Quick refresher or maybe a an overview if you haven't seen this before. In Canvas, we have a component architecture that allows us to source components from

different places. These are the three ones that we ship and contrib modules will be able to extend canvas in the future with other component sources. So single directory components and blocks are Drupal core infrastructure. Single directory components are Drupal's answer to a component-based UI development experience. And blocks have been around for probably multiple decades now. and they allow you to write PHP code, really execute any kind

of logic to get to some kind of output. You can even use SDC's to your output in your blocks, but it's really a system that allows you to do anything. And code components, JavaScript code components, I'm going to actually refer to them as code components in this talk because it's really tiring to say all that every time. So code components, they are canvas's invention and they all

work together in a cohesive way and allow you to produce UI. And the developer experience of code components looks like this. You get to write React, you get to write Tail and CSS, and you get a built-in code editor within the Drupal module with zero configuration. So that's there for you all in the browser. Everything is happening there automatically. But that's not what we are going to

focus on in this talk. Although you will see some of that our focus has been and by our focus I mean the canvas's team focus has been to provide the bestin-class JavaScript tooling for a local development environment. And it's funny because initially we thought we were mostly doing this for developers who prefer to use their own development environment. And that's largely still true. However, there's a new

role that we need to surf here and that is the coding agents. Because turns out if your coding agents can write idiomatic JavaScript. Meaning that you follow all the conventions. You're not trying to make up anything that doesn't exist out there in the JavaScript and React ecosystem. The coding agents will be fantastic at writing code for you. So we set out to build really great tooling for

those agents and of course for humans because in the end I believe that if we make great developer experience we will also make great agentic experience. So we wanted to build good local codebase scaffolding tools. We wanted to make sure that you are able to use functions and components both in the browser and in your local environment. Also something for the future of this talk. When I

say in the browser, I always mean the built-in code editor that's in canvas. So we wanted to code that can work both in the browser and in your local environment. And of course, both for agents and humans, we want great verification tools. Deterministic output, deterministic verification, meaning that you will be able to know if your code is going to or most likely going to work when you

import it in canvas. And we need good agentic skills. And we need a CLI tool that both humans and agents can use. So to get started, I would like to generate a codebase right now. So I don't have anything on my laptop uh that I'm showing you today. I'm going to write that now on the fly. So I'm going to just copy paste this command. This is

going to what this does is it will download this package, the Drupal canvas create package from npm on the fly. It will download its latest version. That's to make sure that you're not using a cached version or an older version of it. and then we will see what else happens. So, right off the bat, it asks me my app's name, which I'm going to just name Chicago.

And it asks me to select a template. Now, Aqua Nebula is the official recommended one. It also happens to be the same component library that Aqua Source customers get when they when they launch a website on Aqua Source as a as a starter point. But today I'm going to use this other one which I created. Uh I call it canvas starter. It's a bit more experimental and

um and we're going to use this for the demo. It just fetched a git repository and then this tool this Drupal canvas create tool realized that there are agentic skills in this repository. Now agentic skills are not that new anymore. uh they have been around for at least two three months in the mainstream but all these coding agents here in this list they they don't they don't

read them from the agents/skills directory so that's why we created this small tool that allow you to let's say that you want to use clot code then I just select it and then it will set up the sim links but other agents like ampex geminy cli and all the others they are reading from this universal location/skills. So now this tool notice that I'm using npm as my

package manager. If I had used pnpm, this would have used pnpm to install all my dependencies. So it just created a new repository for me. And if I go into this repository, you can even see that it created an initial commit saying that I started this codebase with this version of this create tool. So, let's open up the code. No, I'm not going to update it now.

So, what you see here is a codebase entirely only for your UI. You can keep it separate from your Drupal codebase. You don't have to, but it's a really nice way. This is what I actually call a decoupled UI development workflow. And you will see more more elements of that workflow in this presentation. But the very first element is that you can have a separate repository only

for your UI components. So if we start looking at here then we can see how the components are implemented and I'm going to open up the hero component as a start and you can see a component. ML file. If you have written an SDC before, this schema that we support here is a subset of the SDC schema. Pretty much the same, but it's not accurate to say

it's fully the same. Um, but this is the same way as you would write an SDC. The more interesting file is this one. And I hope you noticed the extension that was not supported before. So, this is written in Typescript. JavaScript is still supported. Of course, you don't have to use TypeScript if you don't want to, but I'm showing the latest features for you. So, I wanted

to make sure that we are using TypeScript. And in the second line, this is what I was talking about when I said that I want code. I want JavaScript functions and modules that work both in the browser in canvas, which I will show you in a minute, and here in this local codebase. And then some type imports from local types and from react itself. And this class

variance authority. U this is something that canvas bundles uh by default. It has always bundled that ever since we released code components because it's a really nice and useful utility to author code. Other than that it's really just Tailwind and React code here. Nothing very important. Now, if I want to look at this this component in my local environment, I said I want to be able to

work in a local environment. So, in my previous demos of this, and you may have seen this before, this was storybook. The way to demonstrate these components were storybook. Now, we can still do that. I could still go ahead and write a story. This is just a a regular React component. There is nothing really special about it. But we created a dedicated tool and we call that

canvas workbench. Now this is already hooked up in this repository for the dev command. So I'm going to run it and going to open it up in my browser. And you can see right away that I see a fully assembled page here. That is because there is also, if I go back to this repository, there's also a pages folder with a home.json file in it. This allows

us to write a complete component tree in a Why is that great? Because we can see how these components will look like if we put them on a page in canvas. So, this is not in canvas yet. This is a local development tool. and showing you the sidebar here. I have all the components from this codebase explored. Now, typically with storybook, this would mean that you need

to install storybook and you need to do a bunch of set setup steps and after that you need to write the stories and then these components start appearing. Here we explore and discover all the components by default. You don't have to do anything for these components to show up in this local tool. So I can browse all the components that I have in my codebase and the

default tab here is always going to be how the component will look like when you use it in canvas. That's why if I go to my grid component, I don't see anything because it's just a big one slot. You actually have to pull stuff into it. That's why we developed the concept of mocks in canvas workbench. The six card grid here is a mock. I wrote that

as a simple JSON file in my code. So if I go back and look at the grid component, I have a mock.json file and this defines how this mock how this component tree should be rendered. This gives me a full-blown development environment. And basically we replace the need for storybook. Storybook is fantastic. I don't think it's it's fully obsolete but maybe in the future once we add

more features into workbench it becomes obsolete for example accessibility checks automated in storybook fantastic uh automated tests built on top of vest and storybook fantastic we can still add some of these features which we find relevant what I love about canvas workbench and you might ask why why are you guys competing with storybook the reason is that because this can behave exactly how we want in canvas

and we don't I mean storebook is a very generic tool. This is our tool for canvas only. So I think it's really great and and what's also great about it is that out of the box you don't have to write any mocks. We can just run a single command. Basically, it it's it's zero configuration unless you have some very exotic uh repos repository structure, but it's able

to discover all the components in your codebase and just present it here and then your local coding agent can look at how those components look like. You can use a skill like the agent browser skill from Verscell or Playright CLI. Agent browser is actually faster. That's what I recommend. But you can use all these skills and then your coding agent can use this as a verification environment.

It's non-deterministic. It's really just visually and the HTML markup can be verified by the agent here. But I think it's a really great step towards making things more verifiable for the agent. And then for pages, what's coming here and what what's really exciting is that if you look at this page here, I didn't write this by hand. I mean most of this code is not written by

hand. It's just reviewed by me. But uh this page was generated by an agent and that's what actually we are going towards. We want to be able to generate full pages in a local environment without having a Drupal setup at all. We want to push it to Drupal, of course, and I'm going to demonstrate how that works. But for now, this is all just running locally, and

it gives me a preview of how this all will look like in Canvas. So, enough talk. Let's hop over to Canvas and see how to make this happen. Now I have no components here and I started with the stark theme which gives me little to no CSS that to that is to make sure that all the CSS I want comes from my codebase and not from the

theme. This is actually something where the experience can be a bit rough around the edges. If you have an existing theme and if you want to develop code components on top of it, well, you need to make sure that the CSS will play well and something where the code components are really advanced or a bit more advanced than some of the themes is the use use of

CSS cascade layers and the problem is that we put everything in cascade layers with the code components. Now, if you have a theme that doesn't use cascade layers and it has very aggressive CSS resets, that can get into some problematic um situations because because the non layered CSS will always take precedence over the ones inside cascade layer. So, this is something that we we we are still

figuring out how to do. Right now, the safest best way is to start with no CSS from a theme and build everything with code components. But of course, you can mix and match, but you really need to know what you're doing. Okay, so I said we're gonna push all these components to Canvas, but I haven't set anything up yet. So, let's get to it. Um, one thing

I did, I enabled the canvas ooth module. That's a subm module that is shipped with the canvas module itself. So, I can now just go and create the required configuration for it. So, Canvas Oath is using the simple OOTH module and I need to create a a consumer because I'm going to use a CLI tool to push all these components into Canvas. I'm going to enlarge this

a bit. So, I just need to give it a label. I'm going to use uh the client ID CLI. I will need to set a secret which is going super secret. And I need to enable the client credentials grand type and just enable all of these. Well, I actually don't need these for the demo. I'm just picking those two, but it's a good idea to to uh

enable all of those. And I need to provide a user that's not the anonymous user. That's the only important thing. This is all documented in the canvas oath readme. And you only need to do this once. So, I know this is not great, but you need to do it once. And we are working on a better solution. But this is it. My Drupal site is actually ready

to receive components. And before I do that, remember the codebase is brand new. So I haven't done anything. What I want to do there is create Oh, I'm already in the folder. Good. So I just need to copy this.env.example and have it as myenv file. And then in here I want to edit this file and I need to point at the URL of my site which is

running with DDEV. And I already added the client ID, CLI and a secret that matches these. So I don't need to do anything else. Another configuration option that I would have if this was something that I created in uh from scratch, there is this file canvas.config.json. We introduced this last week. So this is very new. U this is to tell the discovery process both for the CLI

tool and workbench where your components live and where your global CSS is. That's it. There are other configuration options. They are all documented. Um but this is going to be enough to get us started. So how do we do that? I already have the canvas CLI tool installed. So I can just run npx canvas push and then all these components will end up in my Drupal site.

This is different. If you have seen a demo of this before, the push command is like five days old in the in in the merge repository. Uh so this is very very new. Um previously it was the upload command. We are deprecating the upload command and we will not allow granular uploads anymore. So we are making the push and and also spoiler alert there is a pull

command coming. Um we are making them atomic meaning that if you are pushing changes you're pushing everything and there are good reasons to do that. Um one of them will be shown in this demo but right now push will send everything to canvas. So let's see how that looks. I'm refreshing this page and this will give me all the components here. Let's reduce this a bit and

now I can start using them and when I drag them on you have seen this before inside workbench and it looked exactly the same. So we got a nice preview of this. So there's nothing really surprising how this looks in canvas and it just keeps working here and I can for example change this image to a different one if I wanted or make other content updates of

course. What I can also do here is I can just rightclick this and edit the code. And even though this is TypeScript, even though this was coming from a local codebase, I can make any changes I want And I get the preview here, the mobile version because the preview has this smaller space. And I can make updates to this code however I want. One thing I want

to show here is if you look at this code, we are outputting this image in in an image tag. And obviously that's not going to be great because this image can be really large. So we want to optimize that. It's not going to give us a great lighthouse score uh unless we do this. So I'm going to import a component called image from Drupal canvas. If you

have worked with Nex.js before, you may have used the Nex.js image component. This is basically that we extracted the NexJS image component and made it work with the Drupal back end except with the Drupal backend you don't need to do any kind of setup and we're using image styles on the back end to generate everything for you on the fly. So this is zero config. Again, I

just import an image component from here and I go and where I normally have an image tag. All I do is this. And then I get the image fully optimized for me. And if I go to the preview and open up my dev tools, you see all these size variants in an src set attribute. And now I could go ahead and add add the sizes attribute to

make sure this is really fully optimized for the use cases I want. But really we have this all built in. And all I had to do was importing one component from the Drupal canvas package which we publish on npm. So you can use it in any codebase. And this already works. Now I just made that change. I want to publish it. now I want to switch over

to my local codebase and do a pull instead of a push because I just made some changes to a component. This is going to pull everything. And now if I do a get status, I can see that the hero component has some changes and I get the change I just made in the browser. Now you can imagine that this can be automated with continuous integration. You can

set up two-way synchronization which is a bit more complicated. Um or you can do one-way sync if you if you just uh designate your local codebase as the source of truth. So I just got this change in my local environment. Fantastic. What is next? I want to go back to the hero component. uh open it up one more time. And now we just optimized one of the

shortcomings. But if I look closer to this code, I see a button outputed. But if I go to workbench, I actually see the same button elsewhere and no button component here in the sidebar. So let's change that. But I don't want you to see uh while while I'm doing that because the image optimization was very simple. This requires a bit more work. So I want to go

back to the slides and talk about agentic skills because we have them. And uh before I do that uh I want to copy paste this prompt open up my open code and do the change here. So the prompt, oops, that's not the prompt. This is the prompt. So I actually want the hero and pricing table components um render a button component, a shared button component instead of

the inline markup. There are more more components here. And there is actually an example prompt in this repository uh that will not name all the specific components uh and the AI will figure out what components need to be refactored. I want to go a bit faster than that to show you things in this presentation. So that's why I'm calling out the components that I want refactored. And

right off the bat, I'm getting a skill named canvas component definition used. So what is You may have heard about this registry created by Versell. This is called skills.sh and this is where a lot of JavaScript projects are pushing agentic skills. And an [clears throat] agentic skill is is there for you to expand the capabilities of your agent. And the idea is that they are progressively disclosed

in the context window and only the skills are used hopefully uh that you need. And this is a big collection of skills. And here you can search for no sorry Drupal canvas. And you see all these skills already showing up in this registry. And if you click one of them, it will give you a command npx skills add uh and it will allow you to install the

skill from the repository. And this will help your agent do better work. For example, here this is using the component metadata, component definition, and a lot of other skills that I have which are already included in this repository. So if you use the create tool, you don't have to install these skills. If you have a brand new project and you want to use the Drupal canvas skills,

this is the way to do it. You just run this command and install all of them from your uh install all of them from from that So going back to my open code, seeing where it is. Uh it's still working. So while it does that, I want to show you something else. How are we going to make sure that the code that is generated is going to

actually work in canvas other than obviously reviewing it and understanding it because we don't want to do that uh without understanding. So for example, here's my hero component open. Maybe let's not edit this because that would be bad if we both edited the same. So I'm going to just open up navigation instead. And here for example, let's say that we don't provide this default export. Now my

ID is telling me that something is off and it is using ESLint to do the validation and make sure that we are doing everything according to the Drupal canvas recommended ESLint config because this is another package that we published on npm which you can install in any codebase that you have and then you just import it this way and you will get well this is the recommended

package there is one that's called that's called required Those are the ones that actually need to pass in order for your component to work in canvas. And there aren't as many rules. The the one that I just showed you, we need to make sure that there's a default export. A named export is not enough. That's because of how we render things. And that's that's just the way

it is. And there are a few smaller ones. Actually, as we are making progress with all of this tooling, we keep removing stuff from the ESLint rules. I think we're going to reach the point where you don't actually need anything special. is just going to be React and the recommended ones uh are already importing rules from the React accessibility eslink package and the React hooks ESLint package

to make sure that you're adhering to the rules of React hooks and and and some of the stuff that we recommend for you to use. But if you don't want that, it will be uh everything will be available under the required package as well. So let's see how my coding agent uh did. And this is my favorite part. every time it delights me. Whenever it makes changes

and those changes are actually changes made to components, the agent asks me if I want to push these changes to canvas. why not? I just said yes without actually reviewing the code. What could possibly go wrong? It is using the canvas component push skill and it will figure out how to use the CLI tool, a command that you already saw me using and it will yeah it

it's a bit slower than actually typing canvas push but uh but it is automated. So now it is uploading all the components to canvas. Okay, fantastic. Now it's asking me if I want to get commit. Maybe later. So now if I refresh my canvas page here, my Drupal canvas installation, I get the new button link component. And now I could refactor this component here to use a

slot instead instead of the button. Okay. So the next thing I wanted to show you here uh working a bit more on this page is what if I pull in the navigation component for which I actually need the header component and in the navigation. Let's pull in the lo logo as well so it looks good. I'm going to edit the navigation here because it's quick. Let's close

this. And you can notice that these are hardcoded. So that's not great. What do we do about that? I'm going to open up the documentation for canvas and uh not to pretend that I can remember this code and I'm going to go to data fetching and I will look at the examples. And here you can see that the Drupal canvas package also comes with the JSON API

client packaged. So I can just copy paste this code. I'm not going to go through line by line explaining it. Uh I just want to show you that if I put all this in and go back and copy a bit more. So I'm going to use the JSON API client. And this is the interesting part. The JSON API client normally needs a base URL and some other

configuration, but you don't have to do that because we provide it already configured. Not only that, but we provide it with JSON A, which is a really useful D serializer if you want to look at the data that you're fetching. So, I'm going to just copy this part and paste it into my component And then my component will actually fetch these menu items from my Drupal site.

And what's cool about this is that we also use another package called SWR which is a data fetching library from Verscell and it stands for stale while revalidate. So it will do some client side caching for you but we also wrap it and we make sure that we show you the results of what it is fetching here. So you don't need to do a console log to

see how the data is shaped in order to hook things up. It's right here. So I think that is really convenient as convenient as it gets with when when it comes to working with JSON API directly with code. But now you might be thinking what happens now given that I I made those change in canvas. So yes I published it. Great. But now what if I do

another canvas pull? Then I open up workbench because remember those are now fetched from Drupal. So I'm getting an error here and that is because the Drupal JSON API parameters that I don't have installed. So I forgot about that. Let's install it. And also let's install SWR because I need those. So now that those are added to my repository, I just need to go and restart Workbench

and then I'm getting the data fetched here. So we made this possible via a VIT plugin. That VIT plug-in is also published on npm standalone. So if you want to hook things up with any kind of codebase, you can use that. But it's already part of workbench. So what's happening now is that Workbench because I'm fetching data from Drupal is sending a request to my Drupal site

and it is showing you how the fetch data and and the output is going to look like. Okay. So one last thing I want to show you before I go to some more slides is actually I'm not going to show you. I'm I'm going to to just describe. So previously uh we said that third party components sorry third party packages uh from npm that's not really supported

and that is changing with the push command. So the way to do that is you just do an npm install in your local codebase and then you do a push and that way the third party dependency is going to make its way into your Drupal site. You will not be able to edit any code related to that. the in browser code editor will not change but this

way we just introduced support via the CLI tool and via the push command to any kind of thirdparty library. What this means is that you can use shets and UI, you can use just base UI components, you can use any kind of component. The demo I had prepared used the react countup component which I wanted to put into the pricing table. So it has this nice countup

animation, but I want to make sure we have time for questions as well. So I'm going to just skip over that. and also because I wanted to describe this idea as well how to do decoupled front end with Drupal canvas. So I believe that the entire workflow I have just shown is really a solution to many of the issues that the decoupled architecture solves. Because I think

often the reason people went with decoupled is because they wanted not really a decoupled architecture. They wanted a decoupled UI development workflow. They wanted to make sure that they can just write React, write JavaScript, whatever technology you prefer. You want to develop the UI separate from your Drupal application. You want to hire people who are great at writing UI, but maybe I don't know if you remember

Lor's uh uh slide with the Drupalur. Maybe you don't have those people in your team or maybe no one wants to do that. I think often times that's why people chose decoupled uh architectures and of course it creates other problems. Uh but I think this workflow the way you can synchronize everything is really a good solution if that was your main reason. And so how do we

get to rendered content in Drupal canvas? There's this triangle that I draw here. So in order to have that you need a component library where your components are described. You need to know how those are rendered. Your system needs to know how those are rendered. And then you need to express that as a component tree. You need to pick instances of your component library and you need

to express them as a component tree. And that's how you get to render content output. Well, turns out your front-end codebase needs exactly the same. It needs a component library. It needs to compose a component tree that will describe your content output. So to make this work, we can synchronize the component library. You have seen me doing that multiple times. Pushpull. That's all it takes. And then

all you need to do is fetching your component tree from canvas. And that's a solved problem because we have the JSON API module in core. We have the GraphQL contrib module. People have been building decoupled sites for a very long time now. So this is a solved problem and we solved the synchronization part with the CLI tool and we are solving more and more pieces here to

have first class JavaScript support. So I think this is a really viable approach and to recap the tooling that we are building these are all the npm packages that we published. There's the main Drupal canvas package which aims to close the gap between local code and in browser code making sure that data fetching and and all those utilities work at both both places. We have a CLI

tool. We have the create tool which you saw me use to scaffold this repository. We have the ESL config which I showed you. We have workbench as a storebook alternative and we have the agentic skills. What's next is more local agentic workflows. I talked about pages. I didn't mention pages being included in the push command because they are not included yet. But that's what's coming. You can

create the pages locally describing a JSON file and then you just do canvas push and they will and it will create a canvas page entity or update a canvas page entity in Drupal canvas. This is of course good for the one-off pages, but we also want to support content templates this way and global regions, header, footer, etc. We're also introducing a font API. Right now, I didn't

show you in my global CSS. I'm including the inter inter font from the CDN, which is a bit awkward, but we are introducing a first class API. We are going to copy the idea from NXT uh the Vue.js framework. And we are introducing entity reference support in code component. So you can reference entities pass the data as a prop and you can use that data in your

code component. And what's coming a bit later and and this is one of the sour points of of this whole thing serverside rendering it. We will get there. It will take us a bit longer to get there but we will eventually do this. Everything you saw is happening client side. So when you load those pages, those components are going to be hydrated in the browser using Astro

Islands. So it's all client side. And I mentioned the the challenges with compatibility with Drupal themes. And then I talked about image optimization, but I didn't mention these other capabilities that image styles are really good for focal point or other processing needs. Uh we don't have those yet uh in in in the tooling, but these will come later. And I want to close with a quick comparison

of single directory components and JavaScript components when to use which. So if you want to tap into the React and JavaScript ecosystem, if you want to install packages from npm code components that that's native to them with SDC's, you can make it happen. Maybe not fully, but mostly you can make it happen. But it's it's more like a do-it-yourself more challenging way to to add uh those

kind of support for SDC's. But when it comes to the Drupal ecosystem, well, SDC's are first class Drupal core citizen. Code components are provided by a very fastm moving country module. So that's the asterisk. But code components have also been battle tested on a source for many many months now. data fetching. So by the nature of SDC is they're not doing data fetching directly but they are

part of this monolithic rendering engine and they are just the end of that pipeline. So all the rendering and everything from the upper layers are there for SDCs to leverage and code components don't have that. They are written in JavaScript. we need to use the JSON API endpoint endpoints today to do data fetching. We can optimize that further and we will we have plans to do that.

But if today you are building a very data heavy application that needs a lot of caching well they're not there yet and I would say that is when a really good alternative when decoupling can be a really good alternative because if you do that you get SSR whereas for SSR serverside rendering uh I had to to add that red uh rectangle there because we just can't do

that today with code components but it's just how SDC's work so and I already mentioned decoupled front end you can do that with code components and you cannot do that with SDC's the decoupled UI dev workflow that I've been referring to you can actually make something like that happen with SDC's uh I've seen I've seen teams doing different repositories where the front end engineers can write only

twig and and do not have to worry about hooking everything up in in Drupal. Um, but it's it's a bit more challenging to do that. And for code components, it's very easy. And being LM friendly is is one advantage of code components. The the difference between the amount of JavaScript code out there versus Twig code out there when it comes to LLM pre-training cannot be overstated. I

think with that said if you are just working on the markup with twig the tokenization is very similar to JSX so you will leverage that but when it comes to other things other tooling around it the pre-training data is not going to be as rich as it is for code components and la last uh if you cannot really choose canvas lets you mix and match so you

can decide to do maybe some of the data fetching needs as an SDC and go that way. Of course, you need to remember how to write the CSS in your theme. Uh but you can really choose whichever solution you want. And with that, thank you. And maybe we have a couple of more minutes for questions if there's any. [applause] >> Yes. >> So my question is more

about tailwind. I know tailwind It sounds pretty pretty loaded. Does does workbench use just time compiling or tailwind classes? How does that happen? >> So the question was about Tailwind and uh specifically if workbench uses just in time compiling for uh for the Tailwind utility classes because Tailwind is pretty as you said loaded as a as a library. So yes, it does. Uh it actually uses the

same rendering engine that we wrote for the in browser code editor because we needed to do some some tricks to make that happen. Uh in the in browser code editor we are using web assembly. We don't need that in um in in in workbench but we are using the same rendering solution. essential. Mhm. >> And then you're able to pull your I missed it. So how does

it work on the back end? >> Yeah. So the first question was about the workflow with Figma and if I understood it correctly, how would we go about uh importing some of the design tokens and and and h how how would we >> right and yeah and because in in storybook you can you can import those design tokens. Yes. So you can import. So in storybook the

way to import those design tokens is that storybook specific or is is that just you can import it? H how we do you use an add-on to do that? >> Uh yes. Yeah, it sound like so it sounds like based on your answer I'm just repeating for the recording uh story Figma has that option to to push those uh into storybook. So if if that solution is

really specific to storybook then then today it's something where we need to catch up. uh if it's not if it if if maybe there's a library that allows you to to somehow fetch those via HTTP HTTP or or somehow then you can set those up uh in your local codebase. But I I think I think that is that is an area where we would need to uh

do a bit more work to to to make that as seamless as it might be with uh Figma and The second question was about uh a workflow in which multiple developers are working on on on a codebase for code components and and how would they get notified that something is pushed to canvas and they and they need to pull. So we don't have a default answer to

this. It's really up to you how to set up the the workflow at this point. Um, but a good workflow would be to make sure that everything is driven by a GitHub repository for example. And then I think the easiest route is to is to make sure that the GitHub repo is the source of truth. And maybe and and this is where the challenges come like how

would the GitHub repo know that it needs to pull something uh via a a continuous integration workflow. um for for that uh you would need some kind of web hook uh system and that is not something that's that's readily available today. Well, it is available in aquous but uh not not yet um in in in a in a as a solution in canvas. Uh I would say

maybe a periodic pull uh for now uh while this gets more mature. by the way workbench we released it on Friday. So just I just for context this is this is that early. So maybe if you have these very sophisticated needs, I may maybe maybe this is not yet the time to switch from storybook and and from your workflows. But I think this hopefully shows the direction

where we're going. But I think the the answer will be uh a centralized repository and automation set up both ways or just one way uh if you want to keep it more >> Yeah, it's a really great solution. Thank you. >> Uh okay. So one one question. So, so the the question is if if if I see a path in which code components would replace single directory

components and then maybe they would mean the future of Drupal theming. Um I think it depends on who you ask. If you ask me it already has, but that's okay. Uh a more serious answer to that. Uh I think you've seen the comparison. That's where we are today. I think there is still merit to a fully monolithic rendering engine and doing things that way. Now I love

writing front-end code in JavaScript. So I am biased here. Um I I think I think it's a better ecosystem to be in. So maybe but I also think that we don't need to force that opinion on on on everyone. I I I think that the two things can coexist. There is an interesting Drupal core issue that Wolffe Gun Seagler opened last year sometime to to make the

Drupal core theming layer and rendering layer uh fully pluggable and fully replaceable. Maybe that is the way in the future. Is there anything to be aware of? How is like handled with So the question is about caching uh for the how does the caching look like for for for code components. Um so right now they are hydrated in the browser. What that means is that the render

element that outputs these, which is a standard Drupal render element, we call it an Astro Island because we're using the Astro Island implementation from the Astro framework. That is going to be basically an empty div and that's all we can cache today That's why I said that if you if you have really caching heavy needs, this is not there yet. Uh with that said, we have we

have some ideas for for example for data fetching. Um we already have some some logic in the code that is able to understand your so-called data dependencies and able to push that to the back end and so the back end could supply that initial data which would mean that it could live in the render cache. >> Yeah. Not yet. We are not doing that All right, I

think we are out of time and no more questions, but you can you can find me after the talk. I also be in the contribution room um not tomorrow but the day after also some time of tomorrow. So come find me and um I'm always happy to talk about this topic. Thank you. [applause]

From event

DrupalCon

23 Mar 2026 – 26 Mar 2026

All event videos
Back to Watch