diff --git a/frameworks/keyed/mikado/index.html b/frameworks/keyed/mikado/index.html
new file mode 100644
index 000000000..e1fb805d0
--- /dev/null
+++ b/frameworks/keyed/mikado/index.html
@@ -0,0 +1,52 @@
+
+
+
+
+ Mikado-"keyed"
+
+
+
+
+
+
+
+
+
Mikado-"keyed"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frameworks/keyed/mikado/package.json b/frameworks/keyed/mikado/package.json
new file mode 100644
index 000000000..039dff207
--- /dev/null
+++ b/frameworks/keyed/mikado/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "js-framework-benchmark-mikado",
+ "description": "Web's smartest virtual DOM templating engine.",
+ "homepage": "https://github.com/nextapps-de/mikado/",
+ "author": "Nextapps GmbH",
+ "version": "1.0.0",
+ "license": "Apache-2.0",
+ "main": "src/mikado.js",
+ "js-framework-benchmark": {
+ "frameworkVersionFromPackage": "mikado"
+ },
+ "browser": "src/browser.js",
+ "preferGlobal": false,
+ "bin": {
+ "mikado": "./task/compile.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/krausest/js-framework-benchmark.git"
+ },
+ "scripts": {
+ "compile": "node task/compile && echo Compile Complete. && exit 0",
+ "build": "node task/compile src/template.html && node task/build DEBUG=false ENABLE_CACHE=false BUILD_LIGHT=false && exit 0",
+ "build-prod": "npm run build"
+ },
+ "dependencies": {
+ "mikado": "0.0.69"
+ },
+ "devDependencies": {
+ "google-closure-compiler": "^20190904.0.0-nightly",
+ "html2json": "^1.0.2"
+ }
+}
diff --git a/frameworks/keyed/mikado/src/bench.js b/frameworks/keyed/mikado/src/bench.js
new file mode 100644
index 000000000..52f2c8c07
--- /dev/null
+++ b/frameworks/keyed/mikado/src/bench.js
@@ -0,0 +1,26 @@
+const { performance, setTimeout } = window;
+
+let startTime;
+let lastMeasure;
+
+export function startMeasure(name) {
+
+ startTime = performance.now();
+ lastMeasure = name;
+}
+
+export function stopMeasure() {
+
+ const last = lastMeasure;
+
+ if(lastMeasure){
+
+ setTimeout(function(){
+
+ lastMeasure = null;
+
+ console.log(last + " took " + (performance.now() - startTime));
+
+ }, 0);
+ }
+}
\ No newline at end of file
diff --git a/frameworks/keyed/mikado/src/config.js b/frameworks/keyed/mikado/src/config.js
new file mode 100644
index 000000000..8a1178925
--- /dev/null
+++ b/frameworks/keyed/mikado/src/config.js
@@ -0,0 +1,23 @@
+/**
+ * @define {boolean}
+ */
+
+const DEBUG = false;
+
+/**
+ * @define {boolean}
+ */
+
+const BUILD_LIGHT = false;
+
+/**
+ * @define {boolean}
+ */
+
+const ENABLE_CACHE = false;
+
+/**
+ * @define {string}
+ */
+
+const RELEASE = "browser";
diff --git a/frameworks/keyed/mikado/src/data.js b/frameworks/keyed/mikado/src/data.js
new file mode 100644
index 000000000..7a0a2f369
--- /dev/null
+++ b/frameworks/keyed/mikado/src/data.js
@@ -0,0 +1,39 @@
+const ADJECTIVES = ["pretty", "large", "big", "small", "tall", "short", "long", "handsome", "plain", "quaint", "clean", "elegant", "easy", "angry", "crazy", "helpful", "mushy", "odd", "unsightly", "adorable", "important", "inexpensive", "cheap", "expensive", "fancy"];
+const COLOURS = ["red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black", "orange"];
+const NOUNS = ["table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger", "pizza", "mouse", "keyboard"];
+
+const len_ADJECTIVES = ADJECTIVES.length;
+const len_COLOURS = COLOURS.length;
+const len_NOUNS = NOUNS.length;
+
+let _nextId = 1;
+
+export function buildData(count){
+
+ if(count === 1){
+
+ return {
+
+ id: _nextId++,
+ label: ADJECTIVES[_random(len_ADJECTIVES)] + " " + COLOURS[_random(len_COLOURS)] + " " + NOUNS[_random(len_NOUNS)]
+ }
+ }
+
+ const data = new Array(count);
+
+ for(let i = 0; i < count; i++){
+
+ data[i] = {
+
+ id: _nextId++,
+ label: ADJECTIVES[_random(len_ADJECTIVES)] + " " + COLOURS[_random(len_COLOURS)] + " " + NOUNS[_random(len_NOUNS)]
+ };
+ }
+
+ return data;
+}
+
+function _random(max){
+
+ return (Math.random() * max) | 0;
+}
\ No newline at end of file
diff --git a/frameworks/keyed/mikado/src/main.js b/frameworks/keyed/mikado/src/main.js
new file mode 100644
index 000000000..61736e8e8
--- /dev/null
+++ b/frameworks/keyed/mikado/src/main.js
@@ -0,0 +1,66 @@
+"use strict";
+
+import Mikado from "../node_modules/mikado/src/mikado.js";
+import template from "./template.es6.js";
+import { buildData } from "./data.js";
+import { startMeasure, stopMeasure } from "./bench.js";
+
+const root = document.getElementById("tbody");
+const mikado = new Mikado(root, /** @type {Template} */ (template), {
+
+ "store": true,
+ "loose": true,
+ "reuse": false
+
+}).route("run", function(){
+ if(DEBUG) startMeasure("run");
+ mikado.render(buildData(1000));
+ if(DEBUG) stopMeasure();
+})
+.route("runlots", function(){
+ if(DEBUG) startMeasure("runlots");
+ mikado.render(buildData(10000));
+ if(DEBUG) stopMeasure();
+})
+.route("add", function(){
+ if(DEBUG) startMeasure("add");
+ mikado.append(buildData(1000));
+ if(DEBUG) stopMeasure();
+})
+.route("update", function(){
+ if(DEBUG) startMeasure("update");
+ for(let i = 0, item, len = mikado.length; i < len; i += 10){
+ item = mikado.item(i);
+ item.label += " !!!";
+ mikado.update(i);
+ }
+ if(DEBUG) stopMeasure();
+})
+.route("clear", function(){
+ if(DEBUG) startMeasure("clear");
+ mikado.clear();
+ if(DEBUG) stopMeasure();
+})
+.route("swaprows", function(){
+ if(DEBUG) startMeasure("swaprows");
+ mikado.swap(1, 998);
+ if(DEBUG) stopMeasure();
+})
+.route("remove", function(node){
+ if(DEBUG) startMeasure("remove");
+ mikado.remove(node);
+ if(DEBUG) stopMeasure();
+})
+.route("select", function(node){
+ if(DEBUG) startMeasure("select");
+ let selected = mikado.state.selected;
+ if(selected >= 0){
+ selected = mikado.node(selected);
+ if(selected === node) return;
+ selected.className = "";
+ }
+ node.className = "danger";
+ mikado.state.selected = mikado.index(node);
+ if(DEBUG) stopMeasure();
+})
+.listen("click");
diff --git a/frameworks/keyed/mikado/src/template.html b/frameworks/keyed/mikado/src/template.html
new file mode 100644
index 000000000..e8ea00d54
--- /dev/null
+++ b/frameworks/keyed/mikado/src/template.html
@@ -0,0 +1,12 @@
+
+ | {{item.id}} |
+
+ {{item.label}}
+ |
+
+
+
+
+ |
+ |
+
\ No newline at end of file
diff --git a/frameworks/keyed/mikado/src/type.js b/frameworks/keyed/mikado/src/type.js
new file mode 100644
index 000000000..a74e8d4ce
--- /dev/null
+++ b/frameworks/keyed/mikado/src/type.js
@@ -0,0 +1,16 @@
+/** @record */
+function Template() {}
+/** @type {!Template|Array} */
+Template.prototype.i;
+/** @type {!string|Array} */
+Template.prototype.h;
+/** @type {!string|Array} */
+Template.prototype.x;
+/** @type {!string|Object|Array