Create interoperable custom elements—or widgets—from HTML elements without delay, bump, or refresh.

Brickrouge.js is included and built upon by Brickrouge to provide additional features and builtin widgets such as Popovers and Calendars.

Brickrouge.js on GitHub

A simple custom-element demo

Widgets are created from existing HTML and CSS, they just come to life by the grace of Brickrouge.js. Widgets can be embedded by other widgets. The following example demonstrates how a copy widget can embed a time widget. When the "Copy" button is pressed the copy widget creates a copy of its element and insert it before itself, Brickrouge.js takes care of building widgets when the DOM is mutated, the rest is up to you.

The special attribute brickrouge-is is used to recognize widgets from classic HTML elements, it defines the name of the widget factory.

By the way, Brickrouge.js is framework agnostic, only weights 4ko, and includes some nice utilities such as observers.

<div brickrouge-is="copy" class="form-group">
    <time brickrouge-is="time" class="btn btn-sm disabled">&nbsp;</time>
    <button class="btn btn-primary btn-sm">Copy</button>

<script type="text/javascript">

        var n = 1

        function Time(element, options)
   = rainbow(32, ++n % 32)

            function update()
                element.innerHTML = (new Date).toISOString()


            setInterval(update, 1000)

        function Copy(element, options)
            .addEventListener('click', function() {

                var copy = Brickrouge.clone(element)
                , parent = element.parentNode

                parent.insertBefore(copy, element)


        Brickrouge.register('time', function(element, options) {

            return new Time(element, options)


        Brickrouge.register('copy', function(element, options) {

            return new Copy(element, options)


    } (Brickrouge);

    function rainbow(numOfSteps, step)
        // This function generates vibrant, "evenly spaced" colours (i.e. no clustering). This is ideal for creating easily distinguishable vibrant markers in Google Maps and other apps.
        // Adam Cole, 2011-Sept-14
        // HSV to RBG adapted from:
        var r, g, b;
        var h = step / numOfSteps;
        var i = ~~(h * 6);
        var f = h * 6 - i;
        var q = 1 - f;
        switch(i % 6)
            case 0: r = 1; g = f; b = 0; break;
            case 1: r = q; g = 1; b = 0; break;
            case 2: r = 0; g = 1; b = f; break;
            case 3: r = 0; g = q; b = 1; break;
            case 4: r = f; g = 0; b = 1; break;
            case 5: r = 1; g = 0; b = q; break;
        return "#" + ("00" + (~ ~(r * 255)).toString(16)).slice(-2) + ("00" + (~ ~(g * 255)).toString(16)).slice(-2) + ("00" + (~ ~(b * 255)).toString(16)).slice(-2);


Running Brickrouge is used to run Brickrouge. The DOM is observed for mutations and widgets found in document.body are built.

A nice place to call the method is during DOM ready, or as a DOM ready callback:


The MutationObserver interface—or DOM polling if it's not available—is used to automatically build new widgets.


A widget has been built

The widget event is fired after a widget has been built.

 * @param {Brickrouge.WidgetEvent} ev
Brickrouge.observeWidget(ev => {

    console.log('A widget has been built:', ev.widget)


The DOM was updated

The update event is fired after the DOM was updated.

 * @param {Brickrouge.UpdateEvent} ev
Brickrouge.observeUpdate(ev => {

    console.log('This fragment updated the DOM:', ev.fragment)
    console.log('These elements are new widgets:', ev.elements)
    console.log('These widgets have been built:', ev.widgets)


Note: The event is fired a first time after Brickrouge.js is ran.

Brickrouge is running

The running event is fired after Brickrouge is ran.

 * @param {Brickrouge.RunningEvent} ev
Brickrouge.observeRunning(ev => {

    console.log('Brickrouge is running, we can do stuff')



Fork me on GitHub