Basic concepts about WebComponents
Tags: webcomponents, lit, javascript, typescript
Published: 2021-11-15 13:22:08

---
title: Basic concepts about WebComponents
published: true
description: Learn basic concepts for WebComponents to get you introduce to this amazing technology
tags: webcomponents, lit, javascript, typescript
cover_image: https://miro.medium.com/max/1400/1*1TgyU0dctcW2UdZoc3Bb_A@2x.jpeg
---

## What is it?

**WebComponents (WC) is a technology that focuses on the development of native web components** so that they can be used by any page and any framework. To do this, an API has been developed in both JS and browsers to create these new non-native components.


> When we talk about a native component we are referring to HTML elements such as: div, p, main, article, button... A non-native WebComponent would be something like `<my-element></my-element>`

WebComponents is a very basic API and does not have many common features for component development that we can expect from a normal framework such as: `Reactive lifecycle`, `Reactive variables/props` or `Declarative template` among others. That is why it is recommended to use a framework like Lit, Svelte or Angular to create WebComponents and not to do it directly on the JS API. To do this, you must compile your component with your framework to generate a JS file with the `WebComponent` definition. That file later you will be able to take it to any page and import the script in a similar way to:

```html
<!DOCTYPE html>
<head>
	<script type="module" src="./simple-greeting.js"></script>
</head>
<body>
	<simple-greeting name="World"></simple-greeting>
</body>
<!-- 
    Example from:
    https://lit.dev/playground/#sample=examples/hello-world
 -->
```

I recommend [this video](https://youtu.be/4-dYhoZ1Ukw?t=1926) to learn more about the differences between developing directly with the WebComponents API and using a framework to generate WebComponents.

I also recommend taking a look at the [Open WC guidelines, recommendations and best practices](https://open-wc.org/guides/).

## How to generate WebComponents

As discussed above, there are two ways to create WebComponents:

- Directly with the JS WebComponents API: It would be similar to building a web page only with vanilla JS and therefore I do not recommend it unless it is a very basic component.
- With the help of some framework. This is what I recommend.

Webcomponents technology is just starting to be created and new tools will surely appear in the near future.


## Frameworks

Good articles with more detail on this subject::

- [All the Ways to Make a Web Component - Nov 2021 Update](https://webcomponents.dev/blog/all-the-ways-to-make-a-web-component/)
- [Web Component Solutions: A Comparison](https://levelup.gitconnected.com/web-component-solutions-a-comparison-e2fa25c34730)

---

Below is a comparative table based on my personal opinion based on different tests:

| Framework | Made for WC | Small bundle       | External libreries^1 | Buildless          | FrameworkCSS | With TS^2   |
| --------- | ------------------ | ------------------ | ------------------- | ------------------ | ------------ | ------------------ |
| Lit       | :white_check_mark: | :white_check_mark: | :x:                 | :white_check_mark: | :x:          | :white_check_mark: |
| Svelte    | :x:                | :white_check_mark: | -                   | :x:                | :question:   | :question:         |
| Stencil   | :white_check_mark: | :white_check_mark: | :x:                 | :x:                | :question:   | :white_check_mark: |
| Vue       | :x:                | :x:                | :white_check_mark:  | :x:                | :question:   | :question:         |
| Angular   | :x:                | :x:                | :white_check_mark:  | :x:                | :question:   | :question:         |

^1 You can always use vanilla JS libraries
^2 With TS out-of-the-box

### Lit

[![Lit online demo ](https://img.shields.io/badge/lit-demo_online-blue)](https://vite.new/lit-ts)
[![Lit playground](https://img.shields.io/badge/lit-playground-lightgrey)](https://lit.dev/playground/)
[![Lit docs](https://img.shields.io/badge/lit-docs-orange)](https://lit.dev/docs/)
[![Video](https://img.shields.io/badge/lit-video-yellow)](https://youtu.be/4-dYhoZ1Ukw?t=1926)

Positive facts:

- Super light and fast
- Well documented
- No build needed, can be a negative point
- Developed by Google

Negative facts:

- Because it is buildless, you cannot use third party tools such as TailwindCSS with ShadowDOM.
- It is a very strict CSS framework, and works with ShadowDOM, therefore, CSS works only if it is parsed using "`` css`h1 { color: red}`` ``" is allowed. [More info](https://lit.dev/docs/components/styles/).

### Svelte

[![Svelte online demo ](https://img.shields.io/badge/svelte-demo_online-blue)](https://vite.new/svelte-ts)
[![Svelte tutorial](https://img.shields.io/badge/svelte-tutorial-lightgrey)](https://svelte.dev/tutorial/basics)
[![Svelte docs](https://img.shields.io/badge/svelte-docs-orange)](https://svelte.dev/docs)

Positive facts:

- Super light and fast
- Well loved by the community
- Well documented and lots of examples

Negative facts:

- It is a framework that was intended for web development.
- Small community, and therefore, few libraries/plugins compared to React/Angular/Vue.
- There are certain restrictions on how Svelte is made and should be taken into account. [More info](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_reactivity_lifecycle_accessibility)

### Stencil

[![Stencil docs](https://img.shields.io/badge/stencil-docs-orange)](https://stenciljs.com/docs/introduction)

Positive facts:

- Powered by Ionic
- Developed to create Design Systems.

Negative facts:

- Does not have a large community

### Angular/Vue

Positive points:

- Popular frameworks

Negative facts:

- They are not intended for developing WebComponents but web pages.
- WebComponents take up a lot of space
- Compared to the other frameworks in this article, both Angular and Vue are very slow to develop and build.

## Storybook

[![Storybook docs](https://img.shields.io/badge/storybook-docs-orange)](https://storybook.js.org/docs/web-components/get-started/introduction)
[![Storybook example](https://img.shields.io/badge/stencil-example-orange)](https://next--storybookjs.netlify.app/official-storybook/)

Storybook is an open source tool for building components in isolation. It streamlines development, testing and documentation of the user interface. In a "story", which is a web page where a WebComponent or CustomComponent (component developed by Vue, Angular, React...) that you have developed is shown, you can interact with it by changing the props, seeing the events it emits, reading the documentation you have written about the component... which allows you to show your components and do manual testing in a much more comfortable way. Storybook can be integrated with many well-known frameworks and WebComponents.

## TS

In 2021, most JS frameworks also support TS. The use of TS allows to add types to the JS. In addition, tools such as Lit or Stencil, when exporting the component, also export a document with the types of the WebComponent, indicating the props it can receive and the events it can emit and with what parameters.

## Bundler

You can choose any bundler. Although `Open-WC` recommends the use of `web-dev-server`. But `rollup` and `vite` are much faster and also have a lot of plugins. The easiest is to download a `template` from Github.

## Adding styles to WebComponents

To talk about styling in WebComponents, you have to understand that it is the [Shadow DOM](https://developers.google.com/web/fundamentals/web-components/shadowdom?hl=en) that allows CSS styles to be applied only to the elements of the subtree that generates your WebComponent and not to other elements of the web page that hosts the document.

This is very problematic and in general, the only thing I recommend for styling is to use the most basic method: Add classes in the HTML template and then in the CSS of the Shadow DOM by hand, this way you can ease the development process and CI/CD if you add it to the project.

Any other technique that you want to carry out in relation to the WebComponent styles can give problems:

- [Attempting to pass styles from host to WebComponent](https://css-tricks.com/styling-web-components/).
- [Sharing styles for WC and host](https://www.smashingmagazine.com/2016/12/styling-web-components-using-a-shared-style-sheet/)

### Style inheritance

Another option (and which is not recommended in my opinion) is to disable the ShadowDOM of your component and allow your component to inherit styles from the host and, therefore, the WC developer will have to generate the JS file (with the WC definition) and the CSS. Subsequently, the WC user would have to import both the JS file and the CSS file. These styles will also be applied to the host.

> Svelte, for example, uses this technique with the difference that it hashes the CSS classes and in the end the expected result is achieved: That the CSS classes are only applied to the WebComponent. In this way, tools like PostCSS could be used for the development of the WebComponent and not only vanilla CSS.

Still, ShadowDOM is a very immature technology and it is possible that in the future they will improve this aspect.

### Alternatives to TailwindCSS

Alternatives to TailwindCSS can be investigated such as `twind` and `WindiCSS` which are based on `TailwindCSS` but do not work as a PostCSS plugin.

## Conclusion

WC is something different from a web, and therefore, you should use a framework that is specialized in the development of WebComponents. Also, the good practice would be to use ShadowDOM but that as we have already seen can give many problems and it is necessary to use some better alternative.