vue-tui
Health Uyari
- No license — Repository has no license file
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Community trust — 56 GitHub stars
Code Gecti
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Terminal UI framework built on Vue and Vite. Components, layout, focus, HMR, and testing out of the box.
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
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi