Home Manual Reference Source Test

WebCell logo


Light-weight Web Components engine (with MVVM support) based on ECMAScript 2018 & Decorator proposal, powered by the practice & experience from developing EWA v1.0 ~ 4.0.

Join the chat at https://gitter.im/EasyWebApp-js/Lobby

NPM Dependency

FOSSA Status


Basic knowledge

  1. Web components

  2. Custom elements

  3. Shadow DOM

  4. CSS variables

  5. ECMAScript 6+

  6. Decorator

Basic Usage

Quick start

npm init web-cell path/to/your_project

(More configuration & template files can be found in the document of WebCell DevCLI)


Create files as shown below in path/to/your-component directory:


    <textarea onchange="${host.trigger.bind( host )}">
        Hello, ${view.name}!
    <img src="${host.constructor.icon}">
        <tbody data-array="specification"><template>


textarea {
    font-style: italic;


    "name":           "Web components",
    "specification":  [
        {"name": "HTML 5.3"},
        {"name": "DOM 4.1"},
        {"name": "ECMAScript 2018"},
        {"name": "Decorator proposal"}




import { component, blobURI, mapProperty, mapData, on } from 'web-cell';

import template from './index.html';

import style from './index.css';

import data from './index.json';

import icon from './icon.svg';

@component({                 //  Register this class as a Custom Element,
    template, style, data    //  then define static properties
export default  class YourComponent extends HTMLElement {

    constructor() {

        super().buildDOM();    //  This method is necessary when @component or @on is used

    @blobURI    //  Convert Data URL to Object URL, then cache it
    static get icon() {  return icon;  }

    @mapProperty    //  Assign parsed value of Attribute to Property with the same name
    static get observedAttributes() {  return ['value', 'name'];  }

    @mapData    //  Assign Property value to Data with the same name
    attributeChangedCallback() { }

     * Do something after Outside nodes changing
     * @param {Node[]}          assigned - Nodes pluged into a slot
     * @param {HTMLSlotElement} slot
     * @param {?String}         name     - `name` attribute of `slot`
    slotChangedCallback(assigned, slot, name) { }

     * @param {Object} newData
     * @param {Object} oldData
     * @param {View}   view
     * @return {?Boolean} `false` can prevent the view of this Component to rerender
    viewUpdateCallback(newData, oldData, view) { }

     * @param {Object} data
     * @param {View}   view
    viewChangedCallback(data, view) { }

    @on('input',  ':host textarea')
    countLength(event, target) {

        console.log(`Input length: ${target.value.length}`);

    @at(':host *')
    onAny(event, target) { }

    get value() {  return this.$('textarea')[0].value  }

    set value(raw) {  this.$('textarea')[0].value = raw;  }

and then preview them during development with:

web-cell preview


Bundle components to a package with JS modules in it:

web-cell pack


Component library

  1. cell-router

  2. BootCell based on BootStrap v4

  3. Material Cell based on Material Design lite v1.3

  4. GitHub Web widget forked from GitHub jQuery Repo widget

  5. Month picker

Standard specification

  1. HTML 5.3

  2. DOM 4.1

  3. CSS variables

  4. ECMAScript 2018

  5. Decorator proposal


FOSSA Status

WebCell logo by Shi Yao & Xie JiaQi is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License .

Based on a work at https://web-cell.tk/WebCell/ .