CLI Stdout Renderer for Vue

June 6, 2026 ยท View on GitHub

The Vue TUI stdout renderer turns terminal buffer commits into ANSI output for real terminal apps. It is exposed from @simon_he/vue-tui/cli together with the headless Vue runtime, stdin driver, terminal cleanup helper, and Node host adapters.

Use the stdout renderer when your Vue components need to run in a terminal emulator, not just in a browser-hosted terminal view.

What The Renderer Owns

The stdout renderer is an output layer. It does not own your app state, command execution, routing, or data model.

It does own:

  • ANSI cursor movement and styled cell output
  • Optional cursor hiding and restoration
  • Optional alt-screen output
  • Color mode selection
  • Resize tracking when configured
  • OSC8 hyperlink output for safe terminal links

The terminal buffer and scheduler still live in the headless app created by createTerminalApp().

Basic Setup

import { createStdinDriver, createStdoutRenderer, createTerminalApp } from "@simon_he/vue-tui/cli";
import App from "./App.vue";

const app = createTerminalApp({
  cols: process.stdout.columns || 80,
  rows: process.stdout.rows || 24,
  component: App as any,
});

app.mount();

const stdout = createStdoutRenderer(app.terminal, {
  output: process.stdout,
  hideCursor: true,
  altScreen: true,
  colorMode: "auto",
  trackResize: true,
});

const stdin = createStdinDriver({
  dispatch(event) {
    const prevented = app.events.dispatch(event);
    app.scheduler.flush();
    return prevented;
  },
  enableMouse: true,
});

app.scheduler.flush();

process.once("exit", () => {
  stdin.dispose();
  stdout.dispose();
  app.dispose();
});

For signal-safe cleanup, prefer installTerminalCleanup() so cursor, mouse mode, and alt-screen state are restored before the process exits.

Browser DOM vs CLI Stdout

ConcernBrowser DOM rendererCLI stdout renderer
Output targetDOM nodes and spansANSI output to stdout
Input sourceBrowser eventsParsed stdin sequences
LinksSafe DOM anchors when enabledOSC8 links for safe absolute URLs
ResizeContainer-based auto resizeTerminal columns and rows
TestsDOM or headless harnessHeadless harness and stdout smoke tests

Both renderers consume the same terminal model, so most component behavior should stay renderer-agnostic.

Performance Notes

The renderer emits one composed output per flushed frame. For high-throughput apps, keep frequently changing areas small and use render planes so transcript, chrome, input, and overlay updates stay independent. See Performance and High-throughput Rendering for dirty-row and plane guidance.

Terminal Graphics

Terminal graphics are auto-detected from stdout TTY state and common terminal environment variables. Disable them with terminalGraphics: false.

For demos, tests, or hosts that already know the terminal capability, pass an explicit protocol:

const stdout = createStdoutRenderer(app.terminal, {
  terminalGraphics: {
    protocol: "kitty",
    force: true,
  },
});

Use protocol: "iterm2" or protocol: "sixel" for those renderers. Inside tmux, request passthrough explicitly:

const stdout = createStdoutRenderer(app.terminal, {
  terminalGraphics: {
    protocol: "kitty",
    force: true,
    passthrough: true,
  },
});

stdout.dispose() restores cursor and alt-screen state as before. Active terminal graphics are cleared on a best-effort basis during disposal; a failed image clear write does not make dispose() throw.