1.1.0 • Public • Published


The minimalist reactive web-component

Brick is a thin layer to constructs native webcomponents and make them reactive.

Brick is:

  • 👙 minimalist: 74 lines of readable code (non-optimised, uncompressed, no cheating)
  • 🌱 low dependency: its single third-party is the minimalist Petit-Dom which itself has no dependency
  • ♻️ reactive: updating the state recalculate the Virtual Dom when needed
  • 🚀 fast: using virtual dom through a thin layer makes it close to bare-metal
  • 💧 simple: that's Vanilla, there isn't much to know, it's a raw class to extend; no magic

View the demo and their source 🧪.

If you're looking for a higher level Web-Components library, checkout Lego that builds Bricks out of HTML web-component files.

Getting started

Here's a fully working example with no install.

Copy-paste the following in an HMTL file and run it in a browser:

<hello-world name="earth">

<script type=module>
  import { h, Component } from '//unpkg.com/@polight/brick/lib'

  class HelloWorld extends Component {
    init() { this.state = { name: 'world' } }

    toggleName() { this.state.name = 'gaia' }

    get vdom() {
      return ({ state }) => [
        h('p', {}, `Hello ${state.name}`),
        h('button', { onclick: this.toggleName.bind(this) }, `toggle`),

  customElements.define('hello-world', HelloWorld)

There isn't much to explain, but let's detail a little:

  • <hello-world name="earth"> is a web-component. That's native. name="earth" will be sent to the component as { state: 'earth' }
  • init() { this.state = { name: 'world' } } declares the state with it's default values. Also, anything that is declared in the state—and only what is declared here—will be reactive
  • toggleName is a custom method that will be called on click
  • get vdom() is the property that should return a function reprenting your HTML. That function is itself called passing the state argument. It should returns a virtual-dom. If you know virtual-dom, React or elm, this writing will be familiar
  • customElements.define('hello-world', HelloWorld) that's the native way in HTML to declare the web-component.


The best documentation is reading the code.

Because it constructs native webcomponents, all the native web-components documentation applies. You can therefore use slots, disable or enable Shadow DOM, the is attribute and other web-component or HTML capabilities.

In addition, a couple of extra tools are brought by Brick:


this object is made available to the virtual-dom (and CSS styles). It can be reactive (when declared in the init) and can be updated by the app.

State is fed the following way:

  1. declared in the init() with the default values
  2. attributes of the element in the HTML will overwrite the defaults
  3. changing values in the object or on the component attributes will update the values and re-render the component.


You can initialize whatever you need here. That's a convenient instance to declare your reactive state object. When declaring your state here, it's properties will be made reactive.


Must return a function that returns a string, an array or a h() instance. The structure of h() takes 3 arguments: h(<html element (string)>, <attributes (object)>, <children (array, string, or h())>).


Same as vdom(), but returning a CSS style node.

get vstyle() {
  return ({ state }) => h('style', {}, 'p{ color: red }')


A convenient method to call when the component is attached to the dom.


A convenient method to call when the component is removed from the dom.


Working on sources

When participating to Brick you can simply tune the lib/index.js and import it. petit-dom is the only dependency. You may need to adapt its path.


Compiling is convenient but not future-proof. Compilation is done with Rollup and will break in the future. Therefore it is not a high dependency and should never be.

That said, plugins for bundling, minifying and gziping are set up.

You may install them all with npm i --env=dev.

Compiling task

npm run build to bundle/minimify/gzip dist/index.js. That will be bandwidth-friendlier.


npm i @polight/brick

DownloadsWeekly Downloads






Unpacked Size

25.6 kB

Total Files


Last publish


  • vinyll