Nuclo v0.3.21 · zero dependencies

Build explicit
interfaces with
nuclo.

A small, type-safe DOM framework. State stays plain and mutable. You control every update. No proxies, no signals, no virtual DOM.

$npm create nuclo@latest
0
dependencies
175
typed HTML & SVG builders
~15.2KB
gzipped, entire runtime
0
import 'nuclo'

let count = 0

export function Counter() {
  return div(
    p(() => count),
    button("-", { onClick: () => { count--; update() } }),
    button("+", { onClick: () => { count++; update() } }),
  )
}

One explicit cycle.

State-dependent values, no dependency graph, no scheduler. You decide when they run - a single predictable path from your data to the screen.

  1. 01Mutate

    Change your data

    State is plain JavaScript: variables, arrays, objects. Mutate it however you like, as many times as you like.

    todos.push(newTodo) user.name = 'Ada'
  2. 02Commit

    Call update()

    One global function commits your changes. Batch a dozen mutations, then commit once. Nothing renders until you say so.

    update()
  3. 03Patch

    Nuclo syncs the DOM

    Every dynamic expression re-evaluates. Nuclo writes only the values that actually changed to the DOM. No diffing, no re-renders.

    // 2 nodes patched, // everything else untouched
When you mutate state, nothing happens. Call update(), and Nuclo does exactly what you asked. No more, no less.
  1. Explicit is better than implicit

    No proxies track your every move. You mutate state, then you call update(). Cause and effect stay clear and predictable.

  2. Batch freely, update once

    Make ten mutations, then call update() once. The DOM sees only the final state. No renders are wasted.

  3. Functions, not components

    Build with plain JavaScript functions. Nuclo needs no classes, no decorators, and no special syntax. Each function returns DOM nodes. Add onMount and onDestroy as ordinary modifiers, only when you need them.

Built for clarity.

No magic. No surprises. Every update is intentional.

  • 01Explicit

    You own the update cycle

    Mutate freely, then call update() once. Nuclo needs no subscriptions and no schedulers, and it never surprises you with a diff. The DOM syncs when you decide.

  • 02Lightweight

    Zero dependencies

    About 15.2 KB gzipped for the entire runtime. Nuclo needs no compiler and no build plugins. Add one import and start building.

  • 03Typed

    TypeScript-first

    175 fully-typed HTML and SVG builders give you autocomplete for every attribute, style property, and event.

  • 04Precise

    Fine-grained patching

    Dynamic expressions re-evaluate on update(). Only the values that actually changed touch the DOM.

Fast where it counts.

These are independent numbers from js-framework-benchmark, for creating, updating, swapping, and clearing thousands of rows.

js-framework-benchmark · keyedLower is better
  1. Nuclo0.2.24
    1.12
  2. Solid1.9.3
    1.13
  3. Svelte5.42.1
    1.17
  4. Vue3.5.39
    1.31
  5. Riot10.1.2
    1.54
  6. React19.2.0
    1.58
  7. Angular22.0.0
    1.58
  8. Stencil4.23.0
    1.81
  9. Ember7.3.0-alpha.5
    2.06
  10. Knockout3.5.1
    2.26
  11. Qwik1.11.0
    3.29
This score is the duration slowdown against the fastest measured implementation. It is a weighted geometric mean of all keyed benchmarks.Source: js-framework-benchmark

Ready when you are.

Install Nuclo, import it once, and ship UIs that update exactly when you say. You can learn the whole API in an afternoon.

$npm create nuclo@latest