I spent 6 days building my VDOM library as I hated how React handles memo

okovooo2 pts1 comments

Tyaff | VDOM library Tyaff

Tyaff

Tyaff — VDOM library for JavaScript

A lightweight alternative to React in pure JavaScript (ES6+) with its own virtual DOM and philosophy of minimalism.

Key differences from React

memo() blocks only the current component — children continue their own update chains independently, making optimization predictable

Mutable data from any source — a component can read a global store, singleton, or window directly, without props drilling

Pull-based context without Provider/Consumer — any component declares itself a provider via context: { key() { ... } }, children request values via this.context(key)

Props as first argument — signatures like init(props), memo(props), render({ title, items }) allow destructuring props right in the definition

Keys are unique across the entire render — this allows moving components between different parents while preserving instance and state

Main features

Compact and performant — minimal API surface, custom diff/patch algorithm, batching updates via microtask

Optimized for bulk operations — reverse, swap, reparenting faster than React

Dynamic context tree — hierarchical provider system with automatic propagation through HTML tags

Factory-based components — unified creation pattern, automatic method binding, flexible lifecycle

Portals with deferred mounting —!mounting into arbitrary DOM containers with anchor nodes

Key system — user-defined keys are unique across the entire render, automatic path-based keys

Fragment with key — grouping children without wrapper with ability to move groups

Installation

npm install tyaff

Quick start

import { h, Component, mount } from 'tyaff';

const Counter = Component({<br>count: 0,

increment() {<br>this.update({ count: this.count + 1 });<br>},

render() {<br>return h('div', null,<br>h('p', null, 'Counter: ' + this.count),<br>h('button', { onClick: this.increment }, '+')<br>);<br>});

mount(Counter, document.getElementById('app'));

Example: components with context

const ThemeProvider = Component({<br>theme: 'light',

context: {<br>theme() { return this.theme; },<br>toggleTheme() {<br>this.theme = this.theme === 'light' ? 'dark' : 'light';<br>this.update();<br>},

render() {<br>return h('div', null, this.props.children);<br>});

const ThemedButton = Component({<br>render() {<br>const theme = this.context('theme');<br>return h('button', { className: 'btn-' + theme }, 'Button');<br>});

mount(<br>h(ThemeProvider, null,<br>h(ThemedButton)<br>),<br>document.body<br>);

Example: global store

// store.js<br>export const store = { count: 0 };

// app.js<br>import { store } from './store.js';<br>import { h, Component, mount, refresh } from 'tyaff';

const Counter = Component({<br>render() {<br>return h('div', null, 'Count: ', store.count);<br>});

mount(Counter, document.getElementById('app'));

// Update<br>store.count = 55;<br>await refresh(); // all components will re-read the store

Resources

Documentation — full API description, usage examples, lifecycle, context, portals, optimizations

Live example — interactive demo in the browser

Benchmark — performance comparison tyaff vs React (14 scenarios)

Changelog — what’s new in the project

Acknowledgments

This project is a showcase of human-AI collaboration:

Human : architecture, design decisions, code review, vision

Qwen : development, optimization, documentation, visual design

GLM : development, optimization

Gemini : research and analysis (via Search)

Browser Support

Chrome 86+

Firefox 78+

Safari 14+

All modern browsers with ES6 modules support

License

MIT

This site is open source. Improve this page.

component store tyaff context count theme

Related Articles