diff --git a/frameworks/non-keyed/hellajs/index.html b/frameworks/keyed/hellajs/index.html
similarity index 92%
rename from frameworks/non-keyed/hellajs/index.html
rename to frameworks/keyed/hellajs/index.html
index ffb53b7c3..09a4fcab9 100644
--- a/frameworks/non-keyed/hellajs/index.html
+++ b/frameworks/keyed/hellajs/index.html
@@ -9,7 +9,7 @@
 </head>
 
 <body>
-  <div id="root"></div>
+  <div id="app"></div>
   <script src="dist/main.js"></script>
 </body>
 
diff --git a/frameworks/keyed/hellajs/package-lock.json b/frameworks/keyed/hellajs/package-lock.json
new file mode 100644
index 000000000..bb282d610
--- /dev/null
+++ b/frameworks/keyed/hellajs/package-lock.json
@@ -0,0 +1,104 @@
+{
+  "name": "js-framework-benchmark-hellajs",
+  "version": "1.0.0",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "js-framework-benchmark-hellajs",
+      "version": "1.0.0",
+      "dependencies": {
+        "@hellajs/core": "^0.6.3"
+      },
+      "devDependencies": {
+        "bun": "^1.2.9"
+      }
+    },
+    "node_modules/@hellajs/core": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/@hellajs/core/-/core-0.6.3.tgz",
+      "integrity": "sha512-2YkamURMpwCs9KsKwRvnQPx77vDP7Mbj0n9AEX7RSDT2gPEYvj1D/NecX2zeRknhJ0H+UsNUZvAPrBR4wPoHug=="
+    },
+    "node_modules/@oven/bun-linux-x64": {
+      "version": "1.2.9",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@oven/bun-linux-x64-baseline": {
+      "version": "1.2.9",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@oven/bun-linux-x64-musl": {
+      "version": "1.2.9",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@oven/bun-linux-x64-musl-baseline": {
+      "version": "1.2.9",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/bun": {
+      "version": "1.2.9",
+      "cpu": [
+        "arm64",
+        "x64",
+        "aarch64"
+      ],
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "os": [
+        "darwin",
+        "linux",
+        "win32"
+      ],
+      "bin": {
+        "bun": "bin/bun.exe",
+        "bunx": "bin/bun.exe"
+      },
+      "optionalDependencies": {
+        "@oven/bun-darwin-aarch64": "1.2.9",
+        "@oven/bun-darwin-x64": "1.2.9",
+        "@oven/bun-darwin-x64-baseline": "1.2.9",
+        "@oven/bun-linux-aarch64": "1.2.9",
+        "@oven/bun-linux-aarch64-musl": "1.2.9",
+        "@oven/bun-linux-x64": "1.2.9",
+        "@oven/bun-linux-x64-baseline": "1.2.9",
+        "@oven/bun-linux-x64-musl": "1.2.9",
+        "@oven/bun-linux-x64-musl-baseline": "1.2.9",
+        "@oven/bun-windows-x64": "1.2.9",
+        "@oven/bun-windows-x64-baseline": "1.2.9"
+      }
+    }
+  }
+}
diff --git a/frameworks/non-keyed/hellajs/package.json b/frameworks/keyed/hellajs/package.json
similarity index 67%
rename from frameworks/non-keyed/hellajs/package.json
rename to frameworks/keyed/hellajs/package.json
index 3333d21b3..168d84d40 100644
--- a/frameworks/non-keyed/hellajs/package.json
+++ b/frameworks/keyed/hellajs/package.json
@@ -8,15 +8,12 @@
     "frameworkHomeURL": "https://hellajs.com"
   },
   "scripts": {
-    "dev:server": "bun ./index.html",
-    "dev:build": "bun build ./src/main.js --outdir ./dist --minify --watch",
-    "dev": "bun run dev:server & bun run dev:build",
     "build-prod": "bun build ./src/main.js --outdir ./dist --minify"
   },
   "devDependencies": {
     "bun": "^1.2.9"
   },
   "dependencies": {
-    "@hellajs/core": "^0.3.0"
+    "@hellajs/core": "^0.6.3"
   }
 }
\ No newline at end of file
diff --git a/frameworks/keyed/hellajs/src/main.js b/frameworks/keyed/hellajs/src/main.js
new file mode 100644
index 000000000..a6c467e98
--- /dev/null
+++ b/frameworks/keyed/hellajs/src/main.js
@@ -0,0 +1,115 @@
+import { html, signal, batch, forEach, mount } from "@hellajs/core";
+
+const { div, table, tbody, tr, td, button, span, a, h1 } = html;
+
+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 colors = ["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 random = (max) => Math.round(Math.random() * 1000) % max;
+
+let nextId = 1;
+
+const buildData = (count) => {
+  let d = new Array(count);
+  for (let i = 0; i < count; i++) {
+    const label = signal(
+      `${adjectives[random(adjectives.length)]} ${colors[random(colors.length)]} ${nouns[random(nouns.length)]}`
+    );
+    d[i] = { id: nextId++, label };
+  }
+  return d;
+};
+
+const ActionButton = (
+  id,
+  label,
+  onclick
+) =>
+  div({ class: "col-sm-6" },
+    button({ id, onclick, class: 'btn btn-primary btn-block col-md-6', type: "button" },
+      label
+    )
+  )
+
+function Bench() {
+  const rows = signal([]);
+  const selected = signal(undefined);
+
+  const create = (count) => {
+    rows.set(buildData(count));
+  }
+
+  const append = (count) => {
+    rows.set([...rows(), ...buildData(count)]);
+  }
+
+  const update = () => {
+    batch(() => {
+      for (let i = 0, d = rows(), len = d.length; i < len; i += 10) {
+        const label = d[i].label;
+        label.set(`${label()} !!!`);
+      }
+    })
+  };
+
+  const swapRows = () => {
+    const list = rows().slice();
+    if (list.length > 998) {
+      let item = list[1];
+      list[1] = list[998];
+      list[998] = item;
+      rows.set(list);
+    }
+  };
+
+  const remove = (id) => {
+    rows.set(rows().filter(row => row.id !== id));
+  }
+
+  const clear = () => {
+    rows.set([]);
+  }
+
+  return div({ id: 'main' },
+    div({ class: 'container' },
+      div({ class: 'jumbotron' },
+        div({ class: 'row' },
+          div({ class: 'col-md-6' }, h1('HellaJS Keyed')),
+          div({ class: 'col-md-6' },
+            div({ class: 'row' },
+              ActionButton('run', 'Create 1,000 rows', () => create(1000)),
+              ActionButton('runlots', 'Create 10,000 rows', () => create(10000)),
+              ActionButton('add', 'Append 1,000 rows', () => append(1000)),
+              ActionButton('update', 'Update every 10th row', () => update()),
+              ActionButton('clear', 'Clear', () => clear()),
+              ActionButton('swaprows', 'Swap Rows', () => swapRows()),
+            )
+          ),
+        ),
+      ),
+      table({ class: 'table table-hover table-striped test-rows' },
+        tbody(
+          forEach(rows, (row) =>
+            tr({ class: () => (selected() === row.id ? 'danger' : '') },
+              td({ class: 'col-md-1' }, row.id),
+              td({ class: 'col-md-4' },
+                a({ class: 'lbl', onclick: () => selected.set(row.id) },
+                  row.label
+                ),
+              ),
+              td({ class: 'col-md-1' },
+                a({ class: 'remove', onclick: () => remove(row.id) },
+                  span({ class: 'glyphicon glyphicon-remove', ariaHidden: 'true' })
+                ),
+              ),
+            )
+          )
+        ),
+      ),
+      span({ class: 'preloadicon glyphicon glyphicon-remove' }, ''),
+    ),
+  )
+}
+
+mount(Bench, "#app");
diff --git a/frameworks/non-keyed/hellajs/package-lock.json b/frameworks/non-keyed/hellajs/package-lock.json
deleted file mode 100644
index 898746af8..000000000
--- a/frameworks/non-keyed/hellajs/package-lock.json
+++ /dev/null
@@ -1,212 +0,0 @@
-{
-  "name": "js-framework-benchmark-hellajs",
-  "version": "1.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "js-framework-benchmark-hellajs",
-      "version": "1.0.0",
-      "dependencies": {
-        "@hellajs/core": "^0.3.0"
-      },
-      "devDependencies": {
-        "bun": "^1.2.9"
-      }
-    },
-    "node_modules/@hellajs/core": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/@hellajs/core/-/core-0.3.0.tgz",
-      "integrity": "sha512-VhOa8Z5w035qVyqALePnZyVCJskY2yg6iDe/XCRBViEXYz84GfOk9kz9Iqh6CsYmD4e9hhzzKzAooRnsonC6Ag=="
-    },
-    "node_modules/@oven/bun-darwin-aarch64": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/@oven/bun-darwin-aarch64/-/bun-darwin-aarch64-1.2.9.tgz",
-      "integrity": "sha512-A190s6twmzNE6KGVoUxEDQaSebXUY0bTYXUwnAqTWpE/LxkkDZ7VLhDKxe0nqiDOWStSTTXpfZcFp5T2D6c8iQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@oven/bun-darwin-x64": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64/-/bun-darwin-x64-1.2.9.tgz",
-      "integrity": "sha512-s3unmXAPwhaZYpPWoiHb5X6Kxgl7sehf8AB+VQFr85WCaOZoqZhsFl4GzC9G06cdt8pBLxo6l5lI9bi4YmRFBw==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@oven/bun-darwin-x64-baseline": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64-baseline/-/bun-darwin-x64-baseline-1.2.9.tgz",
-      "integrity": "sha512-iCqYZJ1lLlAirNoidH/nAx8Rg8WXoUs/8BjkMaCfjJG99YXSU00LH39MuxJQDRKlgKnd7IWQNJAluPuuB7j1Tw==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@oven/bun-linux-aarch64": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64/-/bun-linux-aarch64-1.2.9.tgz",
-      "integrity": "sha512-tyf8g3H+/CLyItST7/UKkLpRawViaBwroOAOVo0KB4fK+d8WZTDZdHJK9reifs7wwOWhgNrARakPV3d7Sj01HQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@oven/bun-linux-aarch64-musl": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64-musl/-/bun-linux-aarch64-musl-1.2.9.tgz",
-      "integrity": "sha512-IUA/5zR0FqWF6vwg7Ad9gFRbuu/uqGtoNyuq+mcfxZI1HhG0LKWVciuyXe0rpQ9Eno0YkEjcr2z271NTDyeNWg==",
-      "cpu": [
-        "aarch64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@oven/bun-linux-x64": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64/-/bun-linux-x64-1.2.9.tgz",
-      "integrity": "sha512-FoTJmItasGca/GDpwsBPTCbzxGngSgtbXxuV8JjQYDr4YeoRGt6Upc3FH7UV9uBBwxRRYb9sdvyqge1u+Pf/rQ==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@oven/bun-linux-x64-baseline": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-baseline/-/bun-linux-x64-baseline-1.2.9.tgz",
-      "integrity": "sha512-OSa6e8fCgNO8AtM6OL2Tgav+/DiJ5aRuzvAy4lLWQWkmGuzbCqLz/+nJqRrpfL6ALAFDg66ucx8GMa0w2bL4+g==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@oven/bun-linux-x64-musl": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-musl/-/bun-linux-x64-musl-1.2.9.tgz",
-      "integrity": "sha512-xvoKSGzBCeTwNkLnkKlAv1xDw+HCACrUctMXx0eyWr0in/hcsG10QIfeCqec32xdunPLtOPSHv2H1CHO10LB0A==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@oven/bun-linux-x64-musl-baseline": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-musl-baseline/-/bun-linux-x64-musl-baseline-1.2.9.tgz",
-      "integrity": "sha512-/ZEVcz3RQIazmT9825t9+/rckUOz8vSosq4FylE4JCWmTJtQWnrbCYbC7VwdO8XLcf8iFuCM+o0pXkMKch/4iw==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@oven/bun-windows-x64": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64/-/bun-windows-x64-1.2.9.tgz",
-      "integrity": "sha512-jAcIc+NBBzw0VQc+mx/Xwqiv3aubGiXMakYUcr40HpTiuokVn0Kl/U4SKt0IQ12l1wxBpfd6nIwKaXH6Yb3p8w==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@oven/bun-windows-x64-baseline": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64-baseline/-/bun-windows-x64-baseline-1.2.9.tgz",
-      "integrity": "sha512-PhcIgGkcJwylH5MgRidgnMfIELT7a7ikOIbjFkkMTVetm3K1j4U1K2aH9paBrWVs6K57088E2CItCM0rvQd1QQ==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/bun": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/bun/-/bun-1.2.9.tgz",
-      "integrity": "sha512-4l1MnbCk2aEDeyJPs8+St6XsVPwkQvq7XTHG501e7pdFOWvWCy9shfxsHtBwYzmT82gdvx9//AL4qStYfYMO4Q==",
-      "cpu": [
-        "arm64",
-        "x64",
-        "aarch64"
-      ],
-      "dev": true,
-      "hasInstallScript": true,
-      "license": "MIT",
-      "os": [
-        "darwin",
-        "linux",
-        "win32"
-      ],
-      "bin": {
-        "bun": "bin/bun.exe",
-        "bunx": "bin/bun.exe"
-      },
-      "optionalDependencies": {
-        "@oven/bun-darwin-aarch64": "1.2.9",
-        "@oven/bun-darwin-x64": "1.2.9",
-        "@oven/bun-darwin-x64-baseline": "1.2.9",
-        "@oven/bun-linux-aarch64": "1.2.9",
-        "@oven/bun-linux-aarch64-musl": "1.2.9",
-        "@oven/bun-linux-x64": "1.2.9",
-        "@oven/bun-linux-x64-baseline": "1.2.9",
-        "@oven/bun-linux-x64-musl": "1.2.9",
-        "@oven/bun-linux-x64-musl-baseline": "1.2.9",
-        "@oven/bun-windows-x64": "1.2.9",
-        "@oven/bun-windows-x64-baseline": "1.2.9"
-      }
-    }
-  }
-}
diff --git a/frameworks/non-keyed/hellajs/src/main.js b/frameworks/non-keyed/hellajs/src/main.js
deleted file mode 100644
index 57ebad4ac..000000000
--- a/frameworks/non-keyed/hellajs/src/main.js
+++ /dev/null
@@ -1,169 +0,0 @@
-import { html, mount, signal } from "@hellajs/core";
-
-const random = (max) => Math.round(Math.random() * 1000) % max;
-
-const A = ["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 C = ["red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black", "orange"];
-const N = ["table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger", "pizza", "mouse",
-  "keyboard"];
-
-let ID = 1;
-
-const buildData = (count) => {
-  const data = new Array(count);
-
-  for (let i = 0; i < count; i++) {
-    data[i] = {
-      id: ID++,
-      label: `${A[random(A.length)]} ${C[random(C.length)]} ${N[random(N.length)]}`,
-    };
-  }
-
-  return data;
-};
-
-const data = signal([]);
-const selected = signal(undefined);
-
-function create(count) {
-  data.set(buildData(count));
-}
-
-function append(count) {
-  data.set([...data(), ...buildData(count)]);
-}
-
-function update() {
-  const newData = [...data()];
-  for (let i = 0; i < newData.length; i += 10) {
-    if (i < newData.length) {
-      newData[i] = { ...newData[i], label: `${newData[i].label} !!!` };
-    }
-  }
-  data.set(newData);
-}
-
-function remove(id) {
-  const idx = data().findIndex((d) => d.id === id);
-  data.set([
-    ...data().slice(0, idx),
-    ...data().slice(idx + 1),
-  ]);
-}
-
-function select(id) {
-  selected.set(id);
-}
-
-function clear() {
-  data.set([]);
-}
-
-function swapRows() {
-  if (data().length > 998) {
-    const newData = [...data()];
-    const temp = newData[1];
-    newData[1] = newData[998];
-    newData[998] = temp;
-    data.set(newData);
-  }
-}
-
-const { div, table, tbody, tr, td, span, button, a, h1 } = html;
-
-const actionButton = (label, id, fn) =>
-  div(
-    { className: "col-sm-6 smallpad" },
-    button(
-      {
-        id,
-        className: "btn btn-primary btn-block",
-        type: "button",
-        onclick: fn,
-        preventDefault: true,
-      },
-      label,
-    ),
-  );
-
-const jumbo = () =>
-  div(
-    { className: "jumbotron" },
-    div(
-      { className: "row" },
-      div({ className: "col-md-6" }, h1("HellaJS")),
-      div(
-        { className: "col-md-6" },
-        div(
-          { className: "row" },
-          actionButton("Create 1,000 rows", "run", () => create(1000)),
-          actionButton("Create 10,000 rows", "runlots", () => create(10000)),
-          actionButton("Append 1,000 rows", "add", () => append(1000)),
-          actionButton("Update every 10th row", "update", () => update()),
-          actionButton("Clear", "clear", () => clear()),
-          actionButton("Swap Rows", "swaprows", () => swapRows()),
-        ),
-      ),
-    ),
-  );
-
-const dataTable = () =>
-  table(
-    { className: "table table-hover table-striped test-data" },
-    tbody(
-      { id: "tbody" },
-      ...data().map((item) =>
-        tr(
-          {
-            dataset: {
-              id: item.id.toString(),
-            },
-            className: selected() === item.id ? "danger" : "",
-          },
-          td({ className: "col-md-1" }, item.id.toString()),
-          td(
-            { className: "col-md-4" },
-            a(
-              {
-                className: "lbl",
-                onclick: () => select(item.id),
-              },
-              item.label,
-            ),
-          ),
-          td(
-            { className: "col-md-1" },
-            a(
-              {
-                className: "remove",
-                onclick: () => remove(item.id),
-              },
-              span({
-                className: "glyphicon glyphicon-remove",
-                ariaHidden: "true",
-              }),
-            ),
-          ),
-          td({ className: "col-md-6" }),
-        ),
-      ),
-    ),
-  );
-
-const App = () =>
-  div(
-    { id: "main" },
-    div(
-      { className: "container" },
-      jumbo(),
-      dataTable(),
-      span({
-        className: "preloadicon glyphicon glyphicon-remove",
-        ariaHidden: "true",
-      }),
-    ),
-  );
-
-mount(App);