$ rezi
Styling

Styling

Rezi provides direct style props, semantic themes, icons, and focus indicators for terminal UIs.

Rezi provides direct style props, semantic themes, icons, and focus indicators for terminal UIs.

Overview

Rezi styling works at two levels:

Direct Styles : Apply colors and text attributes directly to widgets using RGB values and style objects.

Semantic Themes : Use predefined theme tokens for consistent colors across your application.

Default Recipe Styling

Core interactive widgets are recipe-styled by default (buttons, inputs, textareas, selects, checkboxes, progress, callouts). Use intent on buttons for common “primary/danger/link” patterns, and use manual style props to override specific attributes (they do not disable recipes).

Quick Example

import { ui, rgb, darkTheme } from "@rezi-ui/core";
import { createNodeApp } from "@rezi-ui/node";

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

app.view(() =>
  ui.page({
    p: 1,
    gap: 1,
    header: ui.header({ title: "Styling" }),
    body: ui.column({ gap: 1 }, [
      // Direct RGB styling
      ui.text("Error!", { style: { fg: rgb(255, 100, 100), bold: true } }),

      // Theme-aware styling + composition helpers
      ui.panel("Panel", [
        ui.text("Content here"),
        ui.actions([ui.button({ id: "ok", label: "OK", intent: "primary" })]),
      ]),
    ]),
  })
);

// Apply a built-in theme
app.setTheme(darkTheme);

await app.start();

Style Properties

Every widget that displays text supports a style prop:

type TextStyle = Readonly\<{
  fg?: Rgb24;            // Foreground (text) color
  bg?: Rgb24;            // Background color
  bold?: boolean;        // Bold text
  dim?: boolean;         // Dim/faint text
  italic?: boolean;      // Italic text
  underline?: boolean;   // Underlined text
  inverse?: boolean;     // Swap fg/bg colors
  strikethrough?: boolean; // Strikethrough text
  overline?: boolean;    // Overline text
  blink?: boolean;       // Blinking text
  underlineStyle?: "none" | "straight" | "double" | "curly" | "dotted" | "dashed";
  underlineColor?: Rgb24 | ThemeColor;
}>;

RGB Colors

Create colors with the rgb() helper:

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

const red = rgb(255, 0, 0);
const green = rgb(0, 255, 0);
const customBlue = rgb(100, 150, 255);

ui.text("Colored text", { style: { fg: red, bg: customBlue } });

Text Attributes

ui.text("Bold text", { style: { bold: true } });
ui.text("Italic text", { style: { italic: true } });
ui.text("Underlined", { style: { underline: true } });
ui.text("Curly underline", {
  style: { underlineStyle: "curly", underlineColor: rgb(255, 107, 107) },
});
ui.text("Dim text", { style: { dim: true } });
ui.text("Struck through", { style: { strikethrough: true } });
ui.text("Overlined", { style: { overline: true } });
ui.text("Blinking", { style: { blink: true } });
ui.text("Inverted", { style: { inverse: true } });

Graphics Styling

Graphics widgets use color strings and rendering protocol options in addition to TextStyle.

WidgetStyling knobs
linkstyle, focus state, theme primary/underline defaults
canvasdraw colors (#rrggbb or theme tokens), blitter quality
imagefit, protocol, zLayer, imageId caching
lineChart / sparkline / barChartseries colors, blitter, optional highRes rendering

Use lower-resolution blitters (quadrant, halfblock) for speed; use braille for maximum detail.

Built-in Themes

Rezi includes six built-in themes:

ThemeDescription
darkThemeAyu-inspired dark theme with orange accents
lightThemeClean light theme with blue accents
dimmedThemeReduced contrast dark theme
highContrastThemeWCAG AAA compliant theme
nordThemeNord color palette
draculaThemeDracula color palette

Applying Themes

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

// Set theme at startup
const app = createNodeApp({
    initialState: {},
  theme: darkTheme,
});

// Or switch themes at runtime
app.setTheme(nordTheme);

Semantic Color Tokens

Themes use semantic color tokens for consistent styling:

Surface Colors (bg.*)

  • bg.base - Main background
  • bg.elevated - Raised surfaces (cards, modals)
  • bg.overlay - Overlay surfaces (dropdowns, tooltips)
  • bg.subtle - Subtle backgrounds (hover states)

Foreground Colors (fg.*)

  • fg.primary - Primary text
  • fg.secondary - Secondary/less important text
  • fg.muted - Muted text (disabled, placeholders)
  • fg.inverse - Text on accent backgrounds

Accent Colors (accent.*)

  • accent.primary - Primary accent (actions, focus)
  • accent.secondary - Secondary accent (links, highlights)
  • accent.tertiary - Subtle accents

Semantic Colors

  • success - Success states
  • warning - Warning states
  • error - Error states
  • info - Informational states

Diagnostic Colors (diagnostic.*)

  • diagnostic.error - Diagnostic error underline/color
  • diagnostic.warning - Diagnostic warning underline/color
  • diagnostic.info - Diagnostic info underline/color
  • diagnostic.hint - Diagnostic hint underline/color

State Colors

  • focus.ring - Focus ring color
  • focus.bg - Focus background
  • selected.bg - Selected item background
  • selected.fg - Selected item foreground
  • disabled.fg - Disabled foreground
  • disabled.bg - Disabled background

Border Colors (border.*)

  • border.subtle - Subtle borders (dividers)
  • border.default - Default borders
  • border.strong - Emphasized borders

Border Styles

Box widgets support various border styles:

ui.box({ border: "single" }, [...])   // Single line (default)
ui.box({ border: "double" }, [...])   // Double line
ui.box({ border: "rounded" }, [...])  // Rounded corners
ui.box({ border: "heavy" }, [...])    // Heavy/thick line
ui.box({ border: "dashed" }, [...])   // Dashed line
ui.box({ border: "heavy-dashed" }, [...]) // Heavy dashed line
ui.box({ border: "none" }, [...])     // No border

Shadow Effects

Add depth with box shadows:

// Simple shadow
ui.box({ shadow: true }, [...])

// Custom shadow
ui.box({
  shadow: {
    offsetX: 2,
    offsetY: 1,
    density: "dense"  // "light" | "medium" | "dense"
  }
}, [...])

Spacing

Use the spacing scale for consistent layouts:

KeyValueUse Case
"xs"1Tight spacing
"sm"1Compact elements
"md"2Default spacing
"lg"3Sections
"xl"4Major sections
"2xl"6Page margins
ui.box({ p: "md", border: "rounded" }, [
  ui.column({ gap: "sm" }, [...]),
])
ui.column({ py: "lg", px: "xl" }, [...])

Learn More

On this page