Skip to content
Components for the DOM as you've never seen before
Branch: master
Clone or download
Latest commit c3e4473 May 17, 2019


Social Media Photo by Jonatan Pie on Unsplash

Build Status Greenkeeper badge WebReflection status

Bringing the regularElements goodness to a component based world.

  • no fancy polyfills needed for IE11+, it optionally works even in IE9
  • lightweight as in ~2K lightweight, with also a 1.7K brotli version, for modern browsers only, that drops all unnecessary polyfills for WeakSet, CustomEvent, element.matches(...) or Object.assign 🎉
  • CPU & RAM friendly (100% based on handleEvent through prototypal inheritance)
  • components can exist at any time (past, present, future)
  • no issues with classes, it works well with composed behaviors
  • you can use classes if you like anyway, just pass one instead of a literal!
  • you can use wicked elements as an alternative custom elements polyfill in combination with own element names (e.g. my-wicked-element)
  • you can define multiple behaviors, per same DOM element, through the power of CSS selectors
  • lazy load any component at any time: all their states are uniquely private per selector and per node
  • either attributeFilter or observedAttributes can be used to observe specific attributes

How to

  • as CDN global object, via <script src=""></script>
  • as ESM module, via import wickedElements from 'wicked-elements'
  • as CJS module, via const wickedElements = require('wicked-elements');


Same regularElements API, meaning same customElements API.

// either via classes (ES2015+)
// wickedElements.define('.is-wicked-element', class { ... });
// or literals (ES5+)
wickedElements.define('.is-wicked-element', {

  // always triggered once a node is live (even with classes)
  // always right before onconnected and only once,
  // ideal to setup anything as one off operation
  init: function (event) {
    // the context is actually a private object
    // that inherits the component definition
    // literally: Object.create(component)
    this.el = event.currentTarget;
    // accordingly, you can attach any property
    // and even if public, these won't ever leak
    // (unless you decide to leak the component)
    this._rando = Math.random();
    // you can invoke directly any method

  // regularElements hooks available
  onconnected(event) {},
  ondisconnected(event) {},
  onattributechanged(event) {},

  // and any other event too
  // just prefix a method with `on` and it will
  // be automatically setup for listening
  onclick(event) {},

  // define optional options for specific events
  // any `on${event.type}Options` would work
  onclickOptions: {once: true},

  // if there is a style, it'll be injected only once per component
  // inherited styles won't get injected, and classes needs
  // a static get style() { return '...'; } if this behavior is needed
  style: `
    .is-wicked-element {
      border: 2px solid silver;

  // works well with any 3rd parts library
  //          YOU DON'T NEED hyperHTML
  //          TO USE THIS LIBRARY!
  //          THE NODE CAN BE ANY NODE
  render() {
    this.html`<p>I am rando ${this._rando}</p>`;

  // any object literal syntax available out of the box
  // it's 100% based on prototypal inheritance
  get html() {
    return hyperHTML.bind(this.el);

// you can also attach the wicked element behaviour to
// custom element names without needing customElements
wickedElements.define('wicked-element', {
  // ...

// or even ...
wickedElements.define('[is="wicked-element"]', {
  // ...


These are examples to listen to specific attributes:

// with JS literals
wickedElements.define('...', {
  // ...
  observedAttributes: ['only', 'these'],
  // **OR**
  attributeFilter: ['only', 'these']
  // ...

// with ES classes
wickedElements.define('...', class {
  // ...
  static get observedAttributes() {
    return ['only', 'these'];
  // **OR**
  get attributeFilter() {
    return ['only', 'these'];
  // ...

Bear in mind, if the array is empty all attributes changes will be notified.

You can’t perform that action at this time.