node package manager


virtual-dom view management and routing


A no-frills ES2015 microframework for virtual-dom view management and routing. Because coding UIs shouldn't be rocket science.

import { App, View } from 'panel';
import counterTemplate from './counter.jade';
class CounterApp extends App {
  get SCREENS() {
    return {counter: new CounterView(this)};
class CounterView extends View {
  get TEMPLATE() {
    return counterTemplate;
  get templateHandlers() {
    return {
      incr: () =>{counter: + 1}),
      decr: () =>{counter: - 1}),
new CounterApp('counter-app', {$screen: 'counter', countVal: 1}).start();
  .val Counter: #{counter}
    button.decr(ev-click=handlers.decr) -
    button.incr(ev-click=handlers.incr) +

Inspired by aspects of Mercury, React, Redux, and Cycle, with an emphasis on simple pragmatism over functional purity thanks to Henrik Joreteg's "Feather" app demo. Strips out the opaque abstractions and data flow management layers to provide a straightforward, largely imperative, state-based rendering cycle. Gone are Mercury's channels, React's stores, Cycle's observables, Backbone's event soup and DOM dependencies - a Plain Old Javascript Object represents state, you update it with App.update(), and the DOM gets updated according to the diff. If you really need more fine-grained state management, you can plug in Redux seamlessly (hint: in most apps, you just don't need it).

Magic is kept to a minimum. Core components are virtual-dom for mapping state to DOM, main-loop for batching updates efficiently, and dom-delegator for attaching event handlers to virtual-dom nodes. panel glues these together while adding some facilities for effectively nesting views, standardizing event handlers/template helpers, and providing out-of-the-box routing (based on the Backbone Router). View templates can be made with anything that produces Hyperscript, including raw hyperscript code or Jade or JSX. Close control of component lifecycle events and DOM rendering can be achieved through use of Web Components or virtual-dom widgets.

npm install --save panel

npm test

With debugger: npm run test-debug