Creating Web Components with Stencil.js

January 30, 2018 0 Comments

Creating Web Components with Stencil.js



Raise your hand if you have ever inherited 3000, 5000, 8000+ lines of CSS in a single file, then seen some variation of the same file across many projects. That random submit button with a different hover state is pretty annoying. You want to create a component library but will have to go importing it in all the applications, with varying the stacks, and changing css selectors all over. When you move to a different framework, redo it all over again. Solution: Web Components.

"Web Components is a suite of different technologies allowing you to create reusable custom user interface components — with their functionality encapsulated away from the rest of your code — and utilize them in your web apps." - MDN

A friend recently introduced me to Stencil.js. Blessed be his soul. Stencil, created by the Ionic Framework team, is a compiler that transform your JSX, and Sass to create a Web Components bundled into an NPM package that can be imported into all your projects. We can have one source that will supply consistent branding and behavior through all your applications. Framework agnostic!

Creating a Component

With JavaScript class syntax you can name 'MyComponent'. Specify the HTML tag name and your Sass file with the @Component decorator. Pass props with the @Prop decorator and use them with JSX syntax.

   /component-name       /component-name.tsx


import { Component, Prop } from '@stencil/core'; @Component({ tag: 'my-first-component', styleUrl: 'my-first-component.scss'
export class MyComponent { // Indicate that name should be a public property on the component @Prop() name: string; render() { return ( <p> My name is {} </p> ); }


Their starter template is setup for super easy publishing of your components as an NPM package. Then you can npm install or use the unpkg CDN. Add a script tag in your index.html with the src to your dist file. Voila! Your components are now registered/defined and ready to be used. distribution docs.


<my-first-component name="Max"></my-first-component>

It Gets Better

  • It lazy loads components as they become present in the DOM. If I am understanding correctly, the HTML tags are registered but the rest of the custom content loads once the browser is about to paint each component.

  • Shadow DOM. Your component is scoped. The styles will not conflict!

  • Components have a React-like life cycle. [componentWillLoad, componentDidLoad, componentWillUpdate, componentDidUpdate, componentDidUnload]

  • There is a @State decorator to handle component state.

  • And more...

I'm still learning more about this tool, and looking for other technologies to take into consideration. Let me know what you think and if you have any suggestions.

Check out the docs to try it out.

Launch Video

Tag cloud