ivue
v2.2.2
Published
Infinite Vue – Class Based Architecture for Vue 3
Maintainers
Readme
ivue builds Vue 3 reactivity out of plain TypeScript classes. Real inheritance, real encapsulation, real polymorphism — on ordinary objects, with nothing paid until first access. The whole engine is 1.1 kB gzipped with zero dependencies.
npm i ivue vueimport { Reactive } from 'ivue';
import { ref } from 'vue';
class $Counter {
get count() {
return ref(0)
}
get double() {
return this.count.value * 2 // plain getter — derives on read
}
increment() {
this.count.value++
}
}
export namespace Counter {
export const $Class = $Counter; // raw — children `extends` this
export let Class = Reactive($Class); // reactive — you `new` this
export type Instance = typeof Class.Instance; // the unwrapping-surface type
}<script setup lang="ts">
import { Counter } from './Counter';
const counter = new Counter.Class();
// the state destructure — every Ref the template touches, unwrapped uniformly
const { count } = counter;
</script>
<template>
<button @click="counter.increment()">{{ count }} · double {{ counter.double }}</button>
</template>Full walkthrough: Getting Started.
Why classes, why now
- Native class API —
extends,super, getters, setters, private fields. Real inheritance, encapsulation and polymorphism, all reactive. - Zero-cost creation — instances are plain objects. A million of them take 22 ms — 6 to 132× faster than the alternatives.
- One kilobyte — 1.1 kB gzipped, zero dependencies, 100% test coverage. Stripped to the load-bearing core — an API you can hold in your head.
- Store or ViewModel — the same class serves as a global store, a component ViewModel, or a domain model. One mental model everywhere.
- Composition API, fully compatible — composables plug in through
$-getters. The entire Vue ecosystem works inside your classes. - TypeScript first — writable ref-getters, fully typed instances, precise inference. The type system shaped the engine's design.
One idea, carried through
Reactive() transforms a class once. A getter returning ref() becomes
state: created on first touch, cached, stable forever. A plain getter stays
plain and re-derives on every read — reactive with zero allocation. Methods
bind themselves once, to the right this. Instances stay ordinary objects:
no proxy wraps them, no work happens at construction.
Inheritance, teardown, development parity, speed — consequences of that one move. And composables plug straight in:
import { useMouse } from '@vueuse/core';
class $Pointer {
private get $mouse() {
return useMouse() // created once, encapsulated
}
get x() {
return this.$mouse.x
}
get y() {
return this.$mouse.y
}
}Hard problems, solved together
Each of these sank earlier class-reactivity attempts. ivue ships all of them as one coherent design:
- Bound methods —
this.methodis always correct, always the same reference. - Reactive inheritance — deep
super.x.valuechains resolve level-safe. - Development parity — the same class identity, direct binding, and engine branches in development and production.
- Circular import immunity — the namespace pattern resolves mutual references in any load order.
- Writable getter types — ref-returning getters type as writable; instances fully inferred.
- Deterministic teardown —
$watchscopes per instance,$stopEffects()cleans up. - Minimal memory footprint — derivations are shared prototype getters, not per-instance allocations.
- Hot paths — reads hoist to native ref speed with one line where it matters.
Static() — capability classes (ivue/extras, +0.5 kB)
The same discipline for the class-level surface:
Static() makes static methods lazy-bound
and $-prefixed static getters cached per receiver — a lazy singleton,
an inheritance-aware store, an override seam, and a test boundary in one
declaration. It retires
module-level state outright, and
it has no Vue dependency — the identical idiom runs under Node and Bun:
import { Static } from 'ivue/extras';
class $TextSegmentation {
protected static get $segmenter() {
return new Intl.Segmenter(undefined, { granularity: 'grapheme' });
}
}
export namespace TextSegmentation {
export const $Class = Static($TextSegmentation); // anchor — children extend this
export let Class = $Class;
}Proven at scale
Invar is ivue at full scale: a complete terminal IDE — editor, workspace search, git, terminals, LSP, agents — running on ivue classes under Bun, with no DOM and no Vue components. 94,000 source lines, 345 classes, 35 invariant contracts, zero import cycles, built almost entirely by AI agents holding the Standard as their base discipline.
And at the other end of scale on the web: a 1,000,000-row virtual scroller, a 20,000,000-cell flyweight grid at 4.7 bytes per live cell, and production-grade Quasar field components — all with full source on the page.
The numbers
Measured, not promised — every number carries its method, and the load-bearing benchmarks run live in your browser on the shipped engine:
| creating 1,000,000 instances | time | ivue is |
| --- | --- | --- |
| ivue new Class() | 21.7 ms | the baseline |
| composable factory | 139 ms | 6.4× faster |
| native reactive() | 470 ms | 22× faster |
| memory heap at 100,000 live instances | per instance | 100k total |
| --- | --- | --- |
| ivue class, 30 getters | 3.7 KB | 364 MB |
| composable, 30 closures | 8.0 KB | 781 MB |
| reactive(), fields + getters | 10.4 KB | 1.02 GB |
| composable, 30 computeds | 19.7 KB | 1.93 GB |
Taken all the way down: a fully reactive spreadsheet model holding 20,000,000 live cells at 4.7 bytes each — 8.5× below the plain-object floor — because in ivue, everything costs proportional to what's observed, nothing costs proportional to what exists.
Built for humans and AI
ivue ships with a Standard Operating Manual — the complete authoring standard as annotated templates, rules, and a review checklist. It reads as documentation and works as a drop-in skill for AI coding agents, so generated code follows the same standard your team writes:
npx ivue skill # installs .claude/skills/ivue/SKILL.md, version-locked
npx ivue skill --all # + Codex/Cursor/Copilot where already in useAgents holding the Standard have derived correct patterns its own author never wrote — the manual is a generator, not a catalog. The wider argument: Reactive framework for the AI era.
Go deeper
- Fundamental Principles — the design, from first ideas
- The Engine — how the transform works, internals annotated
- Advanced Patterns — Namespace, Computed Seed, Keyed Version Signals, Flyweight, Static, Backend ivue
- The Blog — 30 posts of measured argument, from circular imports to what JavaScript becomes
Community
Questions, ideas, bug reports — there's no ticket queue, just the people who write the code: Discussions · Issues · Discord · X @evgenykalash · Community page
A note on the size
The complete engine is 1.1 kB gzipped: lazy prototype transformation, bound methods, inheritance, lifecycle ownership, and the public utilities. Development uses that same engine without a second hot-update execution path.
Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. — Antoine de Saint-Exupéry
