Overview of Popular Web Components Frontend Frameworks

This article introduces and compares eight major Web Components frameworks—Stencil, Omi, Slim.js, Polymer, hybrids, X‑Tag, LitElement, and direflow—detailing their features, installation commands, code examples, and practical considerations to help developers choose the most suitable tool for building reusable, standards‑based UI components.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Overview of Popular Web Components Frontend Frameworks

Web Components have become an important technology for building reusable UI elements, and many frameworks have emerged to simplify their development. This article surveys eight prominent Web Components frameworks, providing feature overviews, installation instructions, and code snippets for each.

Stencil

Stencil is a compiler created by the Ionic team that generates standards‑based Web Components using TypeScript and JSX. It offers a project structure, Virtual DOM, JSX, reactive data‑binding, lazy loading, and static site generation.

import { Component, Prop, h } from '@stencil/core';
import { format } from '../../utils/utils';

@Component({
  tag: 'my-component',
  styleUrl: 'my-component.css',
  shadow: true,
})
export class MyComponent {
  @Prop() first: string;
  @Prop() middle: string;
  @Prop() last: string;

  private getText(): string {
    return format(this.first, this.middle, this.last);
  }

  render() {
    return <div>Hello, World! I'm {this.getText()}</div>;
  }
}

Usage example:

<my-component first="Stencil" last="'Don't call me a framework' JS"></my-component>

Omi

Omi, an open‑source framework from Tencent, combines Web Components with JSX/TSX, offering a small size, high performance, Shadow/Light DOM integration, and a React‑like development experience.

$ npm i omi-cli -g   # install cli
$ omi init my-app   # initialize project
$ cd my-app
$ npm start         # develop
$ npm run build     # build for release
import { WeElement, render, h, tag } from 'omi';
import './o-counter';
import './index.css';
import * as css from './index.less';
import logo from './logo.svg';

interface MyAppProps { name: string }

@tag('my-app')
export default class extends WeElement<MyAppProps> {
  static css = css.default;
  abc: string;
  onCountChanged = (evt: CustomEvent) => { console.log(evt.detail); };
  render(props) {
    return (
      <div class="app">
        <header class="app-header">
          <img src={logo} class="app-logo" alt="logo" />
          <h1 class="app-title">Welcome to {props.name}</h1>
        </header>
        {this.abc}
        <o-counter onCountChanged={this.onCountChanged} />
      </div>
    );
  }
}

render(<my-app />, '#root', { ignoreAttrs: true });

Slim.js

Slim.js is a lightweight library (<3 KB gzipped) that provides data binding and extensibility for native Web Components using ES6 classes.

npm install slim-js
# or
yarn add slim-js
import { Slim } from 'slim-js';

const myHTML = `<h1>Welcome, {{this.username}}!</h1>`;

class AwesomeComponent extends Slim {
  constructor() {
    super();
    this.username = 'John Jimmy Junior';
  }
}

Slim.element('my-awesome-component', myHTML, AwesomeComponent);

Polymer

Polymer, developed by Google, offers one‑way and two‑way data binding, good cross‑browser compatibility, and a set of utilities for creating custom elements.

npm install -g polymer-cli@next

git clone https://github.com/PolymerLabs/polymer-3-first-element.git
cd polymer-3-first-element
npm install
polymer serve --open
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
import '@polymer/iron-icon/iron-icon.js';

class IconToggle extends PolymerElement {
  static get template() {
    return html`
      <style>
        :host { display: inline-block; }
        iron-icon { fill: var(--icon-toggle-color, rgba(0,0,0,0)); }
        :host([pressed]) iron-icon { fill: var(--icon-toggle-pressed-color, currentcolor); }
      </style>
      <iron-icon icon="[[toggleIcon]]"></iron-icon>
    `;
  }
  static get properties() {
    return {
      toggleIcon: { type: String },
      pressed: { type: Boolean, notify: true, reflectToAttribute: true, value: false }
    };
  }
  constructor() { super(); this.addEventListener('click', this.toggle.bind(this)); }
  toggle() { this.pressed = !this.pressed; }
}
customElements.define('icon-toggle', IconToggle);

hybrids

hybrids is a JavaScript UI framework that builds full‑featured web apps and component libraries using pure objects and functions while leveraging the native Web Components API.

import { define, html } from "hybrids";

export function increaseCount(host) { host.count += 1; }

export default define({
  tag: "simple-counter",
  count: 0,
  render: ({ count }) => html`
    <button onclick="${increaseCount}">Count: ${count}</button>
  `
});

X‑Tag

X‑Tag, originally from Mozilla and now maintained by Microsoft, wraps the Web Components API to provide a compact, feature‑rich interface, with optional polyfills for older browsers.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Document</title>
</head>
<body>
  <x-clock></x-clock>
  <script src="../src/x-tag-polyfilled.min.js"></script>
  <script src="../src/index.js"></script>
</body>
</html>
// index.js
xtag.create('x-clock', class extends XTagElement {
  connectedCallback() { this.start(); }
  start() { this.update(); this._interval = setInterval(() => this.update(), 1000); }
  stop() { this._interval = clearInterval(this._data.interval); }
  update() { this.textContent = new Date().toLocaleTimeString(); }
  'tap::event'() { if (this._interval) this.stop(); else this.start(); }
});

LitElement

LitElement is a lightweight base class that uses lit‑html to render fast, declarative components into Shadow DOM, reacting to property changes automatically.

<!doctype html>
<html>
<head>
  <script src="https://unpkg.com/@webcomponents/webcomponentsjs@latest/webcomponents-loader.js"></script>
</head>
<body>
  <script type="module">
    import { LitElement, html, css } from 'https://unpkg.com/lit-element/lit-element.js?module';
    class MyElement extends LitElement {
      static get properties() { return { mood: { type: String } }; }
      static get styles() { return css`.mood { color: green; }`;
      }
      render() { return html`Web Components are <span class="mood">${this.mood}</span>!`; }
    }
    customElements.define('my-element', MyElement);
  </script>
  <my-element mood="great"></my-element>
</body>
</html>

direflow

direflow combines React components with Web Components, allowing React‑based UI to be packaged as custom elements.

npm i -g direflow-cli

direflow create
cd <project-folder>
npm install
npm start
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { EventContext, Styled } from 'direflow-component';
import styles from './App.css';

const App = (props) => {
  const dispatch = useContext(EventContext);
  const handleClick = () => {
    const event = new Event('my-event');
    dispatch(event);
  };
  return (
    <Styled styles={styles}>
      <div className="app">
        <div className="top"><div className="header-image"/></div>
        <div className="bottom">
          <div className="header-title">{props.componentTitle}</div>
          <button className="button" onClick={handleClick}>Click me!</button>
        </div>
      </div>
    </Styled>
  );
};

App.defaultProps = { componentTitle: 'Test Direflow', sampleList: [] };
App.propTypes = { componentTitle: PropTypes.string, sampleList: PropTypes.array };
export default App;

Conclusion

Although Web Components are still gaining traction, many major companies have adopted them, and a variety of frameworks now simplify their use. The choice of framework depends on project requirements, performance considerations, and developer familiarity.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

web componentsOmifrontend frameworksLitElementdireflowPolymerSlim.jsStencil
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.