Szymon Kaliski

Vineyard

An exploration of a prototype-inspired ↗ component re-use.

Motivation

Creating reusable components for building applications is a standard industry practice. You don't re-implement a button for every screen of your application, you have a single button component, that's re-used across the code. Maybe all of your buttons are a specific shade of blue, and that's fine, until on one of the pages, you suddenly need a red one, as the on-click handler does something destructive.

A isDangerous property could be introduced, and now all the dangerous buttons are the same shade of red. But what if you also have "warning" buttons, "inline" ones, a "hidden" one just for screen-readers, etc? Maybe it's fine to keep adding properties, or maybe you create a component for each of these uses.

The actual example that motivated this work was when I had a specific well-designed, and well-behaving modal component, used across some project. In one specific place, that modal needed three buttons instead of two, for various reasons. The standard practice would be to decompose the modal into a wrapper that handles some functionality (like displaying as an overlay), some generic body wrapper, and a modal-button section, etc. That's a lot of refactoring to just get a single-use variation to work.

Vineyard is a prototype that explores what it would feel like to be able to override arbitrary properties of any component without extra work.

Project Walkthrough

The leftmost sidebar is a tree of components, organized by ancestry. In this case Blank is the general starting point (a div), then we have a Button component, and Primary is a Button with additional custom styling.

When I make edits to the Button, for example adding an extra border, that propagates to Primary, and all the other children of that component:

I can also make sure that each Button has an icon:

But, decide that I don't want it in the Secondary and Underline styles:

If we come back to the motivating example of building a Modal, here's a general outline of the component:

I can create a variation with three buttons:

Even though I reordered the buttons and modified the subtree of the component, other changes still propagate, like making the default button blue:

Finally, changes I make are recorded in each component, as a side-effect of how the system is implemented:

You can play with Vineyard online ↗.

Open Questions

  • It's hard to judge how something like this would feel if used authentically. The system is hermetically sealed right now, and I think a good next step would be some way to maybe export these components into React. Or maybe even somehow just "use" them, without explicit "exporting"?
  • It's unclear what should happen when a component is removed. For example, in the demo above we use Button all over the place, what should happen if I just remove that component?
  • What about the component functionality? What it would look like to handle button clicks in this system?

References

Vineyard was heavily inspired by Apparatus ↗ (a gift that keeps on giving). Even if we ignore the programming model and the solver, the additional compelling idea is how the component system works:

  • you can add components to other components, and modifying the parent instance, propagates the changes through the tree, which is fairly standard
  • you can also override every property that the component has, without "ejecting" it into the current canvas — and the properties that were not overridden, still continue to propagate (which is also the case in Vineyard)
  • even more interestingly, you can do things like reorder the child components, remove some of them, and the property propagation still holds! (which feels fantastic, and is also the case in my prototype)

Self ↗ is another system that works this way that I know of, though probably feels less familiar than Apparatus' or Vineyard's property trees.

Backlinks

  1. 2025-06-30Prototyping Component Re-Use, and the Simplest Whisper Wrapper2