Stencil components in React, Vue, and Angular

Alessandro Genova
3 min readJun 18, 2018

--

[UPDATE: Aug 7, 2018 — Simpler and better intructions]

[UPDATE: Nov 8, 2018 — Update instructions for Stencil ≥ 0.13.x]

Stencil is not a framework. Stencil provides an elegant API that lets developers write components in TypeScript, and then takes care to compile them into completely standard web components (Custom Elements v1) that can be consumed by any framework.

I first heard about Stencil at a talk from Ionic’s Mike Hartington back in January, and thought it was an appealing idea. Unfortunately I didn’t have the time to dive into it back then, but last week I finally set off to write my first Stencil component. The documentation is very good, and I was able to have my first component ready in no time. The trouble started when I tried to include the component in an existing React project. Due to my lack of experience, this simple operation turned into a few very frustrating hours. The documentation provided by Stencil almost gets you there, but I found that it could be more detailed especially for people like me that may find some of the steps not obvious.

I believe Stencil’s technology is great, and I want to help lowering the entry barrier for others by sharing a few things I had to figure out on my own when trying to use Stencil components in React, Vue, and Angular applications.

To keep it short, I will only go over the React example here, but I am including links to equivalent step by step examples I wrote for Vue and Angular on Github.

0: Build a stenciljs component and publish it to npm

Creating your first stencil component is very easy and it is well documented here.

This example will consume two components:

1: Add the component(s) to the app dependencies

Add the component to the app dependencies in package.json

2: Load the component(s)

Import the component in the index.js of the app:

3: Consume the component

It is now possible to use the tag provided by the stencil components in the render function of any react component.

Appendix: Attribute vs Prop

oc-molecule-vtkjs has a property named cjson that expects a complex object.

Strings and numbers can be passed directly as attributes to a stencil component.

One way to pass a complex object to a component could be to JSON.stringify() the object and thenJSON.parse() it inside the component. But this round trip can be expensive, and it would be a good idea to pass the object directly as a prop.

React doesn’t provide a convenient way to distinguish between attributes and props, so a little work is needed to achieve this.

In the end, it just boils down to saving a reference to the element of the stencil component, and then set the property directly in the javascript code.

To make this operation easier, it can be convenient to create a reusable utility function wc.

And then use it in the jsx to bind events and properties to the webcomponent this way:

Conclusion

Writing reusable web component with Stencil is easy. The same Stencil component will be able to run inside a React, a Vue, an Angular app, or whichever framework will come out next month.

Resources

Stencil components in React

Stencil components in Vue

Stencil components in Angular

--

--