Skip to content
🇨🇭Functional custom elements with hooks and enhancers.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
media Update logo and small copy changes Mar 16, 2019
site @ f4c5481 Update logo and small copy changes Mar 16, 2019
.eslintrc.yml Use babel eslint for dynamic import in pwa Feb 10, 2019
.travis.yml Exclude git submodules for Travis Feb 18, 2019
fixtures Add hugo site for fixtures, and more later Jan 27, 2019
karma.conf.js Add decoupled hooks enhancer Feb 16, 2019
yarn.lock Update logo and small copy changes Mar 16, 2019


Build Status codecov Badge size code style: prettier

npm: npm install swiss-element --save


Swiss provides a functional way of defining custom elements.

Example - Counter

import { html, render } from 'lit-html';
import { element, renderer } from 'swiss-element';
import { useState } from 'swiss-hooks';

function Counter(element) {
  const [count, setCount] = useState(0);

  return html`
    <a href="#" @click="${() => setCount(count + 1)}">
      Clicked ${count} times

element('s-counter', Counter, renderer(render));

A starter app is available at

Example - Hello world

  element('hello-world', ({ w }) => `Hello ${w}`, ['w'])()
).w = 'world';


element(name, comp, [enhancer], [options]) ⇒ HTMLElement

Defines a custom element in the CustomElementRegistry which renders the component which is passed as an argument.

Kind: global function

Param Type Description
name string The tag name for the custom element.
comp function The component that is rendered in the element.
[enhancer] function The element enhancer. You may optionally specify it to enhance the element with third-party capabilities such as middleware, custom renderer, public API, etc. The only element enhancers that ship with Swiss are applyMiddleware and renderer.
[options] Object | Array Options object or observedAttributes only array for shorter syntax.
[options.observedAttributes] Array Attributes to observe for adding, removing or changing which will trigger a component update if needed.
[options.extends] string Specifies the built-in element your element inherits from if any (e.g. extends: 'button').
[options.shadow] 'open' | 'closed' Defines the shadow root mode, by default no shadow root is created and everything is rendered straight on the custom element. The options object is also passed to all the enhancers.


applyMiddleware(...middleware) ⇒ function

Middleware lets you wrap the element's render method for fun and profit. The key feature of middleware is that it is composable. Multiple middleware can be combined together, where each middleware requires no knowledge of what comes before or after it in the chain.

Kind: global function

Param Type Description
...middleware function Functions that conform to the Swiss middleware API. Each middleware receives SwissElement's render function as a named argument, and returns a function. That function will be given the next middleware's render method, and is expected to return a function of fragment calling next(fragment) with a potentially different argument, or at a different time, or maybe not calling it at all. The last middleware in the chain will receive the real element's render method as the next parameter, thus ending the chain. So, the middleware signature is ({ render }) => next => fragment.

renderer(customRenderer) ⇒ function

Adds a simple way to define your own renderer. Verified libraries working by passing just the render or patch function:

  • Lighterhtml
  • Lit-html
  • HTM-Preact
  • Superfine

Kind: global function

Param Type Description
customRenderer function A function that takes the custom element root and a function html which once executed renders the created dom nodes to the root node of the custom element.


Why another dude?

There are dozens of custom element libraries out there, sorry to say, I didn't find one that fit my exact requirements.

  • No ES6 classes and classical inheritance hyperHTML-element, lit-element, skatejs
  • Choose your own render engine neverland, hybrids
  • Opt-in web component features like ShadowDOM and minimal polyfill requirements switzerland, haunted

Swiss doesn't use ES6 classes, Proxy, Shadow DOM (can be configured), etc because IE11 should still be easy to support. The only needed polyfill is the one for window.customElements.

<script src=""></script>


  • Augmentor the only dependency that provides the hooks
  • React for the hooks concept
  • Redux for concepts and adapted docs (writings docs is hard (:)
You can’t perform that action at this time.