Creating Web Components with Stencil.js
Tags: webcomponents, react, vue, stencil
Published: 2018-01-27 00:28:07

---
title: Creating Web Components with Stencil.js
published: true
description: Stencil.js is a tool to create and share Web Components. It allows for easier migration between frameworks as well as sharing consistent resources across websites.  
tags: Web Components, React, Vue.js, stencil
cover_image: https://cdn-images-1.medium.com/max/1200/1*mX0RCyCC3ZsqTL2jpQU57Q.png
---

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](https://developer.mozilla.org/en-US/docs/Web/Web_Components)


A friend recently introduced me to [Stencil.js](https://stenciljs.com/). 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. 

/components
&nbsp;&nbsp;&nbsp;/component-name
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/component-name.tsx
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/component-name.scss 

```javascript
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 {this.name}
      </p>
    );
  }
}
```

####Distribution

Their [starter template](https://github.com/ionic-team/stencil-component-starter) 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](https://stenciljs.com/docs/distribution).   


####Usage

```HTML
<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](https://stenciljs.com/docs/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](https://stenciljs.com/docs/intro) to try it out. 

### Launch Video 
{% youtube UfD-k7aHkQE %}