Web Components for Cross-Framework Component Libraries
An argument with example for delivering cross-framework component libraries using Web Components.

The Challenge of Using Web Components
Several years back, mid-2017, I wrote a series of articles on Web Components, starting with Web Components by Example: Part 1. At that time, I ended that series with:
If you are already using React, however, there is really little reason to use web components; React components provide the same (and more) functionality and because of the popularity of React there is a thriving ecosystem of React components to use in your applications.
Earlier this year, mid-2019, I revisited Web Components with a series starting with Web Components in 2019: Part 1. Mid-way through the series, I concluded that without using an additional frontend framework, e.g., LitElement or Lightning Web Components, Web Components have serious deficiencies as compared to the current popular frontend frameworks, e.g., React, Angular, or Vue.js.
While Web Components, coupled with an additional frontend framework, has many of the requirements of being a solid frontend application development solution, there are still some challenges with using them:
- First, the obvious problem is that we are back to using an additional frontend framework; something that we conceptually were hoping to avoid by leveraging the browser’s built-in support for Web Components
- There are are no integration libraries for popular data management libraries, e.g, Redux or Apollo Client
- There are no established advanced patterns, e.g., dealing with cross-cutting concerns
- Not many folks are using them; lacks a solid development community
As much as I love the goal of Web Components unifying the fractured frontend development communities (React, Angular, and Vue.js), the current incarnation does not appear to be compelling enough to accomplish this goal.
A Compelling Use Case for Web Components
On the other hand, there is a compelling use case for web components; cross-framework component libraries. For example, let us take a look at the interesting state of the popular Bootstrap component library.
The library is delivered as a combination of CSS and JavaScript (built on top of jQuery); seriously old-school JavaScript. The problem, however, the components it provides do not naturally fit with the more reactive approaches of modern frontend frameworks. To address this, there are framework-specific re-implementations of Bootstrap:
- React has React Bootstrap
- Angular has Bootstrap Widgets
- Vue.js has BootstrapVue
An ideal component library, on the other hand, could be used naturally with all of the frontend frameworks (and even vanilla JavaScript projects). Let us examine the core features of the familiar HTML input element as an example of what we are looking for in an ideal component.
HTML elements, including the input element, are self-contained; they have protected behavior that is isolated from the code that uses them (and visa-versa).
Input elements accept attributes, e.g, value, that allow the code that uses them to impact their behavior.
Input elements emit events, e.g., input events, that allow them to impact the behavior of the code that uses them.
What we just described are the core features of Web Components!
Publishing Web Components
This section is not about existing Web Component UI libraries; for that see the article 9 Web Components UI Libraries You Should Know in 2019.
Also, section is not a tutorial on Web Components; for that see another series of articles that I wrote; starting with Web Components in 2019: Part 1.
As the section title suggests, this section is about how to publish a Web Component to be used by other applications. The described example is available for download.
The example consists of a Web Component as shown:

It is rendered using the hello-world tag. Pressing the increment button increments the top number. Pressing the bottom increment external button causes the component to emit an increment event. The component accepts two attributes; color is used to set the color of the Hello World text and value is used to set the value of the bottom number, e.g, the markup as shown is:
<hello-world color="blue" value="3"></hello-world>
The component is published using the npm feature that allows dependencies to be GIT releases, e.g.,
"dependencies": {
"wc-example": "git://github.com/larkintuckerllc/wc-example.git#0.1.11"
}
note: If this was to be a true publicly published Web Component, one would publish to the npm registry.
The Web Component is published as an ES5 bundle that when loaded defines the hello-world tag. By using ES5 the Web Component can used with projects that still support IE11.
note: Because it is published as an ES5 bundle, applications using it must first load the webcomponent.js polyfills.
Some key observations:
- The example’s name and version are maintained the package.json file
- The main value in package.json refers to the ES5 bundle; it is important to include this file in the GIT repository. Notice that the .gitignore file specifically allows dist/bundle.js to be included
- To emphasize the need for applications using this Web Component to load the webcomponent.js polyfills, the package.json includes a peerDependency for it
Using Inside Another Web Component
Having installed the Web Component as a dependency and installed the webcomponent.js polyfills, we can simply import and use the Web Component as expected in another project’s Web Component.
This example is available for download; the specific use of the Web Component is in src/index.ts.
Using Inside a React Component
Similarly, having installed the Web Component as a dependency and installed the webcomponent.js polyfills, we can simply import and use the Web Component as expected in another project’s React component.
This example is available for download; the specific use of the Web Component is in src/App.tsx.
A couple of observations:
- This example uses React Hooks; required learning some new patterns for me
- This example uses TypeScript and JSX thus requires addition typing to use the Web Component in JSX; see src/types/wc-example.d.ts. I found an article, Consuming a Web Component in React in TypeScript, to be particularly helpful
Using Inside a Vue.js Component
As with the previous examples we install the Web Component and polyfills and import it into another project’s Vue.js component.
This example is available for download; the specific use of the Web Component is in src/components/MyHelloWorld.vue.
A couple of observations:
- First, I had to change the name of the Vue.js component from HelloWorld to MyHelloWorld as the former was conflicting with the Web Component’s hello-world tag
- Having never used Vue.js before, I was surprised how simple and declarative it is. I can start to see why some folks prefer it over other frontend frameworks
Wrap Up
note: You might have noticed that I did not include an Angular example. This is because I used to use Angular (back in the 2.x days) and could not bring myself to look at it again.
Bottom line, I am still not ready to give up on my go-to frontend framework, React, for Web Components as there is no compelling reason for me to do so (for application development). At the same time, if I was in the business of distributing cross-framework component libraries I would seriously consider Web Components as the vehicle.