Skip to main content

Installation

npm install @rezi-ui/core

Overview

@rezi-ui/core is the runtime-agnostic heart of the Rezi framework. It provides:
  • Widget system (60+ built-in widgets)
  • Layout engine with flexbox and grid
  • Composition API with hooks
  • Theme system with semantic tokens
  • Animation primitives
  • Router and state management
  • Drawlist generation (ZRDL protocol)
Important: This package is runtime-agnostic and contains NO Node.js-specific code. For Node/Bun applications, use @rezi-ui/node instead.

Key Exports

Widget Factories

All widgets are accessed through the ui namespace:
import { ui } from "@rezi-ui/core";

const view = ui.column({ p: 1 }, [
  ui.text("Hello, Rezi!"),
  ui.button({ id: "btn", label: "Click me" }),
]);

Widget Reference

See complete widget catalog with examples

App Creation

import { createApp } from "@rezi-ui/core";
import { createNodeBackend } from "@rezi-ui/node";

const app = createApp({
  backend: createNodeBackend(),
  initialState: { count: 0 },
});

app.view((state) => ui.text(`Count: ${state.count}`));
await app.run();

Composition API

defineWidget
function
Create reusable widgets with local state and lifecycle.
import { defineWidget, ui } from "@rezi-ui/core";

const Counter = defineWidget<{ initial: number }>((props, ctx) => {
  const [count, setCount] = ctx.useState(props.initial);

  return ui.row([
    ui.text(`Count: ${count}`),
    ui.button({
      id: ctx.id("inc"),
      label: "+",
      onPress: () => setCount((c) => c + 1),
    }),
  ]);
});

// Usage
ui.column([Counter({ initial: 0 })]);

Widget Authoring

Learn how to build custom widgets with defineWidget

Theme System

import {
  darkTheme,
  lightTheme,
  nordTheme,
  draculaTheme,
  highContrastTheme,
} from "@rezi-ui/core";

const app = createNodeApp({
  initialState: {},
  theme: darkTheme,
});

Animation Hooks

All animation hooks are available from @rezi-ui/core:

useTransition

Tween between numeric values

useSpring

Physics-based spring animations

useSequence

Keyframe-based sequences

useStagger

Stagger animations across items

Control Flow Utilities

each
function
Map over arrays to generate widget children with keying.
show
function
Conditionally render a widget when condition is true.
when
function
Render one of two branches based on condition.
match
function
Pattern matching for conditional rendering.
import { each, show, when, match, ui } from "@rezi-ui/core";

const items = ["Apple", "Banana", "Cherry"];

ui.column([
  ...each(items, (item) => ui.text(item)),
  show(items.length === 0, () => ui.text("No items")),
  when(
    items.length > 5,
    () => ui.text("Many items"),
    () => ui.text("Few items")
  ),
]);

Advanced Exports

Layout Engine

fluid
function
Create responsive values that interpolate based on viewport width.
import { fluid, ui } from "@rezi-ui/core";

ui.box({
  p: fluid({ min: 1, max: 4, minWidth: 40, maxWidth: 120 }),
});

Drawlist Builders

createDrawlistBuilderV1
function
Create ZRDL v1 drawlist builder (legacy).
createDrawlistBuilderV3
function
Create ZRDL v3 drawlist builder (current stable).
createDrawlistBuilderV5
function
Create ZRDL v5 drawlist builder (latest).

Testing

import { createTestRenderer } from "@rezi-ui/core";

const renderer = createTestRenderer({ width: 80, height: 24 });
const tree = ui.text("Hello");
const result = renderer.render(tree);
console.log(result.text); // Rendered output

Debug Tools

debug
function
Log widget tree structure for debugging.
inspect
function
Deep inspection of widget properties.
debugPanel
function
Visual debug overlay with FPS counter and error display.
import { debugPanel, ui } from "@rezi-ui/core";

ui.layers([
  ui.layer({ id: "main" }, myAppContent),
  ui.layer({ id: "debug", zIndex: 1000 }, debugPanel({ position: "top-right" })),
]);

Type Exports

The package exports comprehensive TypeScript types:
  • VNode - Virtual node type
  • App<S> - App instance type
  • WidgetContext<S> - Widget composition context
  • Theme - Theme type
  • TextStyle - Text styling
  • Rgb - Color type
  • All widget prop types: BoxProps, ButtonProps, TextProps, etc.

Module Boundaries

Critical Rules:
@rezi-ui/core MUST NOT import from @rezi-ui/node, @rezi-ui/jsx, or @rezi-ui/native. It is runtime-agnostic by design.
  • @rezi-ui/node → imports @rezi-ui/core
  • @rezi-ui/jsx → imports @rezi-ui/core
  • @rezi-ui/core → imports from node packages ❌

Package Structure

The package provides multiple entry points:
import * as core from "@rezi-ui/core"; // Main entry
import * as widgets from "@rezi-ui/core/widgets"; // Widget types only
import * as theme from "@rezi-ui/core/theme"; // Theme system
import * as layout from "@rezi-ui/core/layout"; // Layout utilities
import * as forms from "@rezi-ui/core/forms"; // Form utilities
import * as router from "@rezi-ui/core/router"; // Router

Version & ABI

import {
  ZR_ENGINE_ABI,
  ZR_UNICODE_VERSION,
  ZR_DRAWLIST_VERSION,
} from "@rezi-ui/core";

console.log(ZR_ENGINE_ABI); // { major: 0, minor: 1, patch: 0 }
console.log(ZR_DRAWLIST_VERSION); // 5

@rezi-ui/node

Node.js/Bun backend

@rezi-ui/jsx

JSX runtime

@rezi-ui/native

Native engine bindings

Build docs developers (and LLMs) love