Skip to content

Instantly share code, notes, and snippets.

@phenaproxima
Last active April 27, 2025 14:41
Show Gist options
  • Save phenaproxima/75e32efe60e67406b9e7d29b98e4bdd8 to your computer and use it in GitHub Desktop.
Save phenaproxima/75e32efe60e67406b9e7d29b98e4bdd8 to your computer and use it in GitHub Desktop.
phenaproxima's human-grokable notes about XB internals

My First Week With Experience Builder

I’m an experienced backend software engineer and Drupal core developer and until a few days ago, I knew basically nothing about Experience Builder (“XB” to the cool kids) except that it’s really neat, and was all the rage at DrupalCon Atlanta. Its internals were a mystery to me, and for the most part, they still are.

But I’ve been partially assigned to actually work on XB this quarter, so I had to dive in and try to learn how it works. Deep breath...

First, I tried reading its documentation: no luck there. The docs are rich in detail, but they're also extremely pedantic, which makes for a soul-sucking read, and they don't explain the big picture that's needed for all those fiddly details to make sense.

XB is also a fast-moving target with an unbelievable amount of complexity. For my money, this is probably one of the most complicated Drupal modules in existence; it’s gotta be right up there with Views.

So here are big-picture learnings that really helped me make sense of this kaiju.

1. XB is visual-first 💡

XB treats a page in the exact opposite way that Drupal historically does. What we’re used to in Drupal is: start with some data, then lay it out in some way. Data first.

XB goes in the opposite direction. First, you make a layout. Then you wire data into it, selectively. There are a few different ways to do that; more on this in a bit.

2. Layouts are surprisingly simple and elegant 😎

Every layout in XB, no matter how big or small, simple or complicated, is made of two parts:

  • The tree: defines what goes where, and what contains what else. This is all it does.
  • The inputs: tells XB how to wire various little data tidbits (from fields, for example) into the layout, to be used in different ways.

XB stores layouts in various places, but all XB layouts consist of these two structures.

3. Every part of the layout is a component 📦

This is familiar to front-end folks. Everything in the layout is a component. Components can have properties (props) of various kinds; some might have no props at all. Components can have slots that contain other components. XB can pull prop values from various places in Drupal.

Internally, every component in a layout has its own unique identifier. (These are usually randomly generated UUIDs.)

4. There are different ways to wire data into a layout 🔌

XB needs to translate Drupal data, which has its own set of assumptions and idiosyncracies, into front-end component props, which have no awareness or understanding of how Drupal works (and rightfully so). There are four ways, but I only know about two right now.

  • Static props have values that are stored with the layout, and don’t change dynamically. They’re not tied to Drupal field values. (Well, sort of; XB actually does some intimidating magic — that I don’t fully understand — whereby it generates a fake field out of thin air to temporarily hold the values. But they’re still not regular, persistent fields like you’d see on a node form.)
  • Dynamic props get pulled in from, say, a node or the current user -- or some other data structure -- dynamically, during rendering and previewing (and, I would imagine, editing). These values aren’t stored with the layout; the layout just stores instructions (“prop expressions”, in XB terminology) for where to get the values from. Conceptually, these are similar to the tokens that Drupalists know and love.

XB refers to these different methods of pulling data into the layout as “prop sources”. As I said, there are more than just static and dynamic prop sources (there are “adapters”, and some other thing whose name eludes me at the moment).

To be clear, a prop is not inherently "static" or "dynamic" -- those are just different ways for a prop to get a value.

5. XB uses “shapes” so that you don’t have to melt your brain every time you want to map a field to a prop 💠

One of the pain points of Layout Builder is that, when you put a field block into a layout, it’ll let you choose any field you’ve got, even the ones that are meaningless to the layout you’re working on. This isn’t great for anyone but it’s especially bad for the content authors who are XB’s target audience.

In XB, let’s say you’re adding on a component that has a prop which wants a URL. (Maybe it’s a link button component or something.) If you want to wire that prop to some Drupal data, it is pointless to even offer you, like, an image field as something you could map to that prop, because that wouldn’t make a whole lot of sense.

But even if you only offer link fields, not all of those necessarily make sense — perhaps the prop only accepts internal URLs, not just any ol’ URL. In a situation like that, it would be a lot better to only show link fields that are limited to storing internal URLs.

XB calls this a “prop shape”. Every prop in a component has a “shape” — that is, the kind of data it can accept and what that data has to look like. XB infers the shape of all components’ props, and the shape of all field values, and ensures that you always match props to an appropriate field. This “shape matching” is complicated and kind of intimidating, and I don’t know how it works, but that’s what it’s there for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment