JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://github.com/xdenser/knockout-component/raw/master/knockout.component.js"></script>
<script src="https://github.com/xdenser/kc-tree-habr/raw/master/tree.js"></script>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>

<div id="container"/>
<script id="singleSelectNodeTemplate" type="text/html">
    <input type="checkbox" data-bind="checked: isSelected"><span data-bind="text: text"></span>
    <!-- ko if: hasChildren -->
    <ul>
        <!-- ko foreach: children -->
        <li data-bind="template : nodeTemplate"></li>
        <!-- /ko -->
    </ul>
    <!-- /ko -->
</script>

JavaScript

var data = { text: "root", children: [], isSelected: false };
_.each(_.range(100),function(i) {
    var o = { text: "Level1-"+i, children: [], isSelected: !!(i%2) };
    _.each(_.range(3),function(j) {
        var o2 = { text: "Level2-"+i*10+j, isSelected: !!(j%2), children: [] };
        _.each(_.range(5),function(k){
            var o3 = { text: "Level3-"+i*100+j*10+k, children: [], isSelected: !!(k%2) };
            o2.children.push(o3);
        });
        o.children.push(o2);
    })
    data.children.push(o);
})

Object.extend = function(destination, source) {
    for (var property in source) destination[property] = source[property];
    return destination;
};

function TreeNodeViewModel(nodeTemplate, data) {
    this.nodeTemplate = nodeTemplate;
    Object.extend(this,data);
    
    this.children = ko.computed(function () {
        return _.map(this.children || [], _.bind(function (c) { 
            return new TreeNodeViewModel(this.nodeTemplate, c);
        },this));
    }, this);

    this.hasChildren = ko.computed(function () {
        return this.children().length > 0;
    }, this);
}

var config = {
    nodeTemplate : "singleSelectNodeTemplate"
};

var rootElement = $('<div />').append($("#" + config.nodeTemplate).html());
$("#container").append(rootElement);

var startTime = new Date();
var root = new TreeNodeViewModel(config.nodeTemplate, data);
ko.applyBindings(root, rootElement[0]);
alert(((new Date() - startTime) / 1000)+"ms");