There’s another working example of Web Components here:
There are a couple of caveats, though.
The first is that Web Components doesn’t expose any way of removing or replacing a custom element definition. There’s customElements.define, and that’s it. That means that if you ever want to change your custom element definition, you have to reload the entire page. This goes against the grain of Observable, which uses dataflow to re-evaluate cells automatically.
The second is that Web Components cannot be statically analyzed. Consider this cell:
Observable has no way of knowing that the <my-element> custom element is defined by the cell called MyElement. And hence you could be creating those custom elements before the custom elements are defined. That might not be a problem—the browser will correct the display for custom elements that already exist in the DOM—but if you depend on certain runtime behavior in the cell that’s creating the elements, it might be surprising.
You can avoid the second caveat by making the dependency explicit by referencing the MyElement class, but it’s a little awkward:
MyElement, html`<my-element mood="happy"></my-element>`