Skip to content

Design Philosophy

Why is Kumiki shaped the way it is? This page condenses the design rationale. For how the 7 layers work in practice, read Thinking in Kumiki; this page is about why they exist at all.

Origins

The premise is simple: if you design from scratch for AI to write the code, human-centered idioms like Hooks and JSX become liabilities. Kumiki began as a test of that premise.

Why not React

React is a human-centered optimum: Hooks, Context, and JSX are idioms refined over nearly twenty years to feel natural to people. As the writer of code shifts to AI, the same machinery becomes friction:

FrictionWhat it costs an AI
Syntactic overheadJSX inflates tokens — closing tags, camelCase attributes, expression embedding
Implicit side effectsuseEffect dependency arrays, stale closures, forgotten cleanup
Order-dependent rulesHooks call order, no Hooks in conditionals or lists
Implicit scopeProvider hierarchies, Context resolved invisibly from descendants
Non-local renderingA parent re-render propagates; suppressing it with memo adds complexity

The pattern: all of these are writable when an AI writes them, and become sharply harder when an AI must fix them or touch them in parallel. When the cause of a bug lives outside the program text the AI cannot reason about it without cramming the entire history into its context window.

Kumiki removes this friction structurally, not by convention.

Design requirements

  1. Token efficiency — the same UI in fewer tokens than React.
  2. Static traceability of side effects — which effect depends on which state, and where it fires, is evident from the syntax alone.
  3. Architectural predictability — bugs localize; errors are machine-readable codes.
  4. Resilience to parallel editing — dozens of agents editing simultaneously must not break the program semantically.
  5. Readability may be sacrificed — whether humans enjoy reading it is a secondary goal. The primary goal is that AI writes and fixes it accurately.

Requirements 1 and (partially) 2–4 are not aspirations — they are measured continuously. See Benchmarks.

Where four independent designs converged

Kumiki did not start as one design. It started as four independent proposals, each from a separate model-assisted exploration that never saw the others.

Comparing them critically revealed that despite entirely different surface syntax, all four converged on the same four cores:

  1. Side effects are explicit descriptors — pure values, not function calls.
  2. Local state is prohibited or minimized — every piece of state is statically locatable.
  3. source ≠ runtime — an IR and a compile step are mandatory.
  4. An append-only causal log — debugging, replay, and audit share one foundation.

The only remaining disagreement was the physical form of the source text. Kumiki is the hybrid: 7 enforced layers and named slots (Pyramid), capability-bearing effect descriptors (IR+Actor / Pyramid), episode log thinking (Loom), parallel editing as referentially-checked ops (Nexus) — with each proposal's known weakness covered by another's strength (e.g. nesting is allowed only inside tiles, so the one-declaration-per-line shape never degenerates into parenthesis hell or assembly).

Lessons taken from prior art

AttemptAdoptedAvoided
ElmComplete side-effect isolation; Result/OptionBoilerplate bloat; rigidity of banning local state outright
UnisonContent-addressable definitionsDisconnection from the text/Git ecosystem
SolidJSFine-grained reactivity, compiled dependenciesHidden tracking scope, signal staleness
Hazel / SubtextTyped holes, zero syntax errorsInput friction
DarkTrace-driven developmentEcosystem lock-in
DatomicAppend-only fact logUnfit for high-frequency updates

Non-goals

Kumiki deliberately does not aim for:

  • Incremental migration of existing React code — zero compatibility; new apps only.
  • Comfortable from-scratch authoring by humans — humans can write it; it is not optimized for that.
  • Macros, plugins, or language extensions — the AI's learning target stays single and closed.
  • Dynamic types — everything is static.
  • Multiple rendering targets — DOM only.

Connect at the boundary, never through the language

The non-goals above imply a positive principle: the language itself never grows holes for interop. Connection to the existing JS ecosystem happens at three boundaries, all outside the language:

  • Inbound — host code injects implementations for declared capabilities (mount(app, target, { providers })); standard capabilities like http.* can be overridden the same way. See Standard Capabilities.
  • Outbound — a Kumiki app embeds into any page as a Web Component (defineKumikiElement). See Runtime.
  • Build@kumikijs/vite lets any Vite project import App from "./app.kumiki", with generated TS types for the providers.

A .kumiki file means the same thing everywhere, because nothing host-specific can leak into it.

The operating model is part of the design

The repository is run on the rule that looking at it resolves every question: questions and bugs are answered by adding working examples and tests, not prose; the spec is normative and every example must compile, build, and survive a smoke test in CI. A language designed for machine consumers needs documentation with the same property.