mini jsx virtual dom
🔧 Install · 🧩 Example · 📜 API docs · 🔥 Releases · 💪🏼 Contribute · 🖐️ Help
$ npm i vdomini
Or directly from jsDelivr:
/** @jsx h */
/** @jsxFrag Fragment */
import { h, Fragment, render } from 'https://cdn.jsdelivr.net/gh/stagas/vdomini/vdomini.min.js'
-
Minimal-to-zero API.
-
Fast. Stable. Predictable.
-
No surprises!
-
Compact. Readable. Hackable.
-
Minimal error surface - With code that tries to do as little as possible there can only be a handful of ways that something can go wrong and when it does it won't be because "issue #47665" hasn't been resolved yet.
-
When an error occurs you can inspect it, you're always one navigation away from its readable source code and the understanding of what caused it and possibly how to solve it.
-
No bells and whistles - All operations are as close as possible to the Real DOM(tm). No fibers, monads, queues, portals, no tons of layers of complexity between your intention and the operation.
-
No learning curve - You already know how to write HTML and to manipulate it using JavaScript. This is only abstracting a few DOM operations, which you also already know.
-
No setup - There are no plugins, transformers, transpilations that you need to learn or specific tools you need to use, besides TypeScript, which is excellent. If you're setup with TypeScript, then this is simply one npm install away. It's more like a library than a framework.
- Fast.
- Tiny. 1.5kb brotli.
- JSX with virtual dom.
- Functional components with props, like usual from React.
- Keyed lists with fast reconciliation only touching the items that changed.
-
Refs - Passing any object to the
ref
attribute will be injected acurrent
property that corresponds to the live dom element. - Reactive Hooks - Only the function component and its children where the hook was captured are going to be rerendered when it triggers.
- BYOB - The hook API is simply holding a reference and using the trigger function. Any kind of hook can be implemented using these primitives. The very basic ones are included simply for convenience and as an example.
/** @jsx h */
/** @jsxFrag Fragment */
import { h, Fragment, render, useCallback } from 'vdomini'
let count = 0
const Counter = ({ count }) => {
const inc = useCallback(() => count++)
const dec = useCallback(() => count--)
return (
<>
count is: {count}
<br />
<button onclick={inc}>increase</button>
<button onclick={dec}>decrease</button>
</>
)
}
render(<Counter {...state} />, document.body)
A more complete example can be seen here.
- render
- useHook
- useCallback
- trigger
- VHook
- current
- h
- Fragment
- FunctionalComponent
- VNode
- VType
- VProps
- VChild
Renders a virtual node on an html Element.
render(<p>hello world</p>, document.body)
Returns a callback that will trigger a rerender on the current component.
let clicked = 0
const Foo = () => <>
{clicked++}
<button onclick={useHook()}>click me</button>
</>
Returns any The hook callback
Wraps a function along with a hook so when called will also trigger that hook.
let clicked = 0
const Foo = () => {
const inc = useCallback(() => clicked++)
return <>
{clicked}
<button onclick={inc}>click me</button>
</>
}
-
fn
function (...args: Array<any>): void Any function to wrap with the hook
Returns any The callback function
Triggers a rerender on a hook.
let hook
const Foo = () => {
hook = current.hook
return <p>{content}</p>
}
render(<Foo />, c)
trigger(hook)
-
hook
VHook The hook to trigger
A hook that enables reactive programming. It can
be obtained using the export current.hook
from inside a functional component and triggered
using trigger(hook)
.
The current
singleton.
Type: Current
Holds a reference to a hook that can be triggered later using trigger.
The virtual node JSX factory. Returns the tree of the node and its children.
const vNode = h('p', { align: 'center' }, ['hello', 'world'])
-
type
any The element type of the virtual node to be constructed. -
props
any? A props object with arbitrary values. -
children
...any A VNode.
Returns VNode
Fragment symbol for JSX fragments <></>.
Functional component interface.
const vNode = h(() => ({ type: 'p', props: null, children: ['hello'] }))
-
props
The properties passed to the component
Returns any The computed VNode.
A virtual dom node.
The VNode type.
Type: (FunctionalComponent | CustomElementConstructor | string | symbol)
VNode propeties.
Type: (Record<string, any> | null | undefined)
A VNode child.
Type: (VNode | string | number | boolean | undefined)
Getting a reference to an element when it is created inside the component:
const Component = () => {
const ref = {
set current(el) {
// el is now the div below
// here we can attach event listeners,
// mutation observers etc.
},
}
return <div ref={ref}></div>
}
All contributions are welcome!
MIT © 2021 stagas