@_hyf0: I wanted to build a toy coding agent. Started by looking into the TUI layer. That rabbit hole turned into a full termin…
Summary
VUE-TUI is a new open-source framework that lets developers build interactive terminal applications using Vue components, with features like flexbox layout, HMR, and a focus system.
View Cached Full Text
Cached at: 05/25/26, 10:35 AM
I wanted to build a toy coding agent. Started by looking into the TUI layer. That rabbit hole turned into a full terminal UI framework.
- Write Vue components for the terminal.
- Develop them with Vite HMR.
Meet VUE-TUI: https://t.co/SOyHgf4zBd https://t.co/IYh6pTuOA0
vuejs-ai/vue-tui
Source: https://github.com/vuejs-ai/vue-tui
vue-tui
Early stage — under active development. Bug reports welcome, but not recommended for production use yet.
Vue for the terminal. Build interactive CLI apps with components, flexbox, and HMR.
- Vue SFC & JSX — write terminal UIs with
<template>, TSX, or both - Flexbox layout — powered by Yoga, the same engine behind React Native
- Focus system — built-in focus management with Tab navigation
- Hot module replacement — instant feedback while developing
- First-class testing — render components, simulate input, assert frames
Packages
@vue-tui/runtime— The core framework. A custom Vue 3 renderer that targets the terminal instead of the DOM. Provides components (Box,Text,Static, etc.), composables (useInput,useFocus,useExit, etc.), and a yoga-based flexbox layout engine.@vue-tui/cli— Development tool. Runvue-tui devto start your app with Vite-powered HMR — edit a.vuefile and see the terminal update instantly.@vue-tui/testing— Test harness. Render components in an isolated fake terminal, simulate keyboard input, and assert on visual output frame by frame.
Quick Example
// src/main.ts
import { createApp } from "@vue-tui/runtime";
import App from "./App.vue";
createApp(App).mount();
<!-- src/App.vue -->
<script setup lang="ts">
import { shallowRef } from "vue";
import { Box, Text, useInput } from "@vue-tui/runtime";
const count = shallowRef(0);
useInput((input) => {
if (input === "+") count.value++;
if (input === "-") count.value--;
});
</script>
<template>
<Box>
<Text>Count: </Text>
<Text bold color="green">{{ count }}</Text>
<!-- try changing this color -->
<Text dimColor> (+/- to change)</Text>
</Box>
</template>
Examples
| Example | Description |
|---|---|
basic-template | Vue SFC with <template> syntax |
basic-jsx | Same app in TSX |
coding-agent | AI coding agent with LLM streaming and interactive UI |
flappy-bird | Physics-based terminal game with reactive state and borders |
Getting Started
npx tiged vuejs-ai/vue-tui-starter my-app
cd my-app
npm install
npm run dev
That’s it — try changing the color or text in App.vue and watch the terminal update instantly while keeping your component state.
To build and run:
npm run preview
Components
| Component | Description |
|---|---|
<Box> | Flexbox container — direction, wrap, align, justify, gap, padding, margin, borders, background |
<Text> | Styled text — color, bold, italic, underline, strikethrough, dimColor, wrap/truncate modes |
<Spacer> | Expands to fill available space (flex-grow: 1) |
<Newline> | Inserts line breaks (configurable count) |
<Static> | Renders a list of items once, above the redrawn region |
<Transform> | Applies a string transform function to each rendered line |
Hooks
| Hook | Description |
|---|---|
useInput(handler, opts?) | Handle keyboard input — receives (input, key) with modifier and arrow key detection |
useFocus(opts?) | Component-level focus — returns { isFocused, focus } |
useFocusManager() | App-level focus control — focusNext(), focusPrevious(), focus(id) |
useExit() | Programmatic app exit — returns exit(error?) |
useTerminalSize() | Reactive terminal dimensions — { columns, rows } |
useStdin() | Access stdin stream and raw mode control |
useStdout() | Write directly to stdout |
useStderr() | Write directly to stderr |
Testing
The @vue-tui/testing package renders components in an isolated environment and lets you simulate input and assert visual output:
npm install -D @vue-tui/testing
import { defineComponent, ref } from "vue";
import { expect, test } from "vitest";
import { render } from "@vue-tui/testing";
import { Box, Text, useInput } from "@vue-tui/runtime";
test("counter responds to + and - keys", async () => {
const Counter = defineComponent(() => {
const count = ref(0);
useInput((input) => {
if (input === "+") count.value++;
if (input === "-") count.value--;
});
return () => (
<Box>
<Text>Count: {count.value}</Text>
</Box>
);
});
const { lastFrame, stdin } = await render(Counter);
expect(lastFrame()).toContain("Count: 0");
await stdin.write("+");
expect(lastFrame()).toContain("Count: 1");
await stdin.write("-");
expect(lastFrame()).toContain("Count: 0");
});
Development
Requires pnpm and Node.js 22+.
pnpm install # install dependencies
vp run ready # lint, typecheck, test, and build (the full check)
vp run -r test # run tests across all packages
vp run -r build # build all packages
vue-tui dev # start an example with HMR
Caveats
- vue-tui enables raw mode by default so the terminal won’t echo keystrokes into your UI.
- Ctrl+C still exits —
exitOnCtrlCdefaults totrue. - For pure-output tools that don’t need input suppression, pass
rawMode: falsetomount().
Credits
vue-tui started as a Vue port of Ink, the library that proved terminal UIs could be built with the same component patterns we use on the web. The component model, yoga-based layout, focus system, rendering pipeline — all of it originates in Ink’s design, adapted to follow Vue’s philosophy and conventions. Thank you to Vadim Demedes, Sindre Sorhus, and the Ink contributors for creating such a solid foundation.
License
MIT
Yunfei He (@_hyf0): Been bored lately, so I’m gonna build a toy coding agent. Kicking off with the TUI layer!
Similar Articles
@jakevin7: Here's a hot take: TUI will gradually decline or even become obsolete. I haven't used Claude Code in a long time. I almost exclusively use Slock. For ad-hoc tasks, I now use Codex Desktop more, occasionally Claude Desktop. It makes me rethink TUI…
This article discusses the trend of TUI (Terminal User Interface) gradually declining in AI programming tools. The author argues that as model capabilities improve, TUI will be replaced by CLI+server architectures or Web UI, and shares personal experience switching from Claude Code to Slock, Codex Desktop, and other tools.
@leon7hao: https://x.com/leon7hao/status/2059191435753410630
Sharing personal experience of using Codex and Claude Code to refactor front-end UI via vibe coding. Disclaimer: not professional design, for technical reference only.
@tom_doerr: Generates UI with 67% fewer tokens than JSON https://github.com/thesysdev/openui…
OpenUI is an open-source framework for generative UI that uses a streaming-first language to produce UI with up to 67% fewer tokens than JSON, including a React runtime and chat interfaces.
@hasantoxr: I'm uninstalling Cursor and every other AI coding tool after finding this. It's called DeepSeek TUI. A full coding agen…
DeepSeek TUI is a new open-source CLI coding agent built in Rust that runs locally in the terminal using DeepSeek's API. It offers features like file editing, shell command execution, and multiple control modes without needing a browser or IDE plugin.
@GoSailGlobal: ByteDance quietly open-sourced the GUI Agent route, and it's more solid than imagined. UI-TARS-desktop (GitHub 29.4k) packs two things in one repo: · Agent TARS: A general multimodal Agent framework, one-click CLI launch, can run in the terminal…
ByteDance open-sourced the UI-TARS-desktop project, containing a general multimodal Agent framework Agent TARS and a local GUI Agent UI-TARS Desktop, supporting real-world tasks in terminal/browser, based on UI-TARS vision model and Seed-1.5-VL, under Apache 2.0 license.