A Virtual DOM implementation for Unity. Build UIs declaratively with a React-like API — virtual tree diffing and patching keep your GameObjects in sync efficiently.
- Unity 6000.5 or later (Unity 6)
Add to Packages/manifest.json:
{
"dependencies": {
"com.uzimaru.veauty": "https://github.com/uzimaru0000/Veauty.git"
}
}Veauty is split into four packages:
| Package | Role |
|---|---|
com.uzimaru.veauty (this package) |
VTree types, Diff algorithm, Hooks, [Component] attribute |
com.uzimaru.veauty-gameobject |
Renderer, Patch applicator, VeautyObject entry point |
com.uzimaru.veauty-ugui |
uGUI widgets, Presets API (V.Text, V.Button, etc.) |
com.uzimaru.veauty-uitoolkit |
UI Toolkit elements, VeautyElement entry point, style attributes |
Node<T>/Node<T,U>— basic node with tag, attributes, and children.Uis the Unity component type.KeyedNode<T,U>— keyed node for efficient list diffing.FunctionComponentNode— function component, created via[Component]attribute orFunctionComponents.Create().
APIs for managing state and lifecycle inside function components.
// State — triggers re-render on change
var count = Hooks.UseState(0);
count.Set(x => x + 1);
// Ref — mutable value that does NOT trigger re-render
var renderCount = Hooks.UseRef(0);
renderCount.Current++;
// Effect — runs on mount/unmount or when dependencies change
Hooks.UseEffect(() =>
{
Debug.Log("mounted");
return () => Debug.Log("unmounted"); // cleanup
}, new object[] { /* dependencies */ });Mark a static method with [Component] to turn it into a function component. An ILPostProcessor wraps the method body in FunctionComponents.Create() at compile time, so callers invoke it like a regular method.
// Definition
[Component]
static IVTree Timer(float interval)
{
var elapsed = Hooks.UseState(0f);
Hooks.UseEffect(() => { /* ... */ }, new object[] { interval });
return new Node<GameObject>("Timer", /* ... */);
}
// Call site — no wrapping needed
Timer(1.0f)Without [Component], hooks would run in the caller's scope and would not have their own lifecycle (mount/unmount).
Source lives in SourceGenerator~/. To rebuild after making changes:
cd SourceGenerator~
dotnet build -c Release
cp bin/Release/netstandard2.1/Veauty.CodeGen.dll ../CodeGen/Diff<T>.Calc(oldTree, newTree) computes patches; Patch.Apply() applies them to the existing GameObject tree.
| Patch type | Behavior |
|---|---|
Redraw |
Replace the node |
Attrs |
Apply attribute diff |
Attach |
Change the typed component |
Append |
Append children |
RemoveLast |
Remove trailing children |
Remove |
Remove the node |
Reorder |
Reorder keyed children |
- Manual — getting started, architecture, hooks, function components, diffing
- API reference — every public type and member
- Agent guide — rules, patterns and pitfalls for coding agents
- Changelog