Skip to content

Repository files navigation

react-terminal

Lightweight terminal UI for React with streaming output, ANSI colors, command history, and AI/LLM mode.
Headless hook + styled component.

npm versionbundle sizelicense

Live Demo

react-terminal demo

Why react-terminal?

  • Headless + Styled: Use useTerminal() hook for full control, or drop in <Terminal> for instant UI
  • ANSI Colors: Built-in parser for 16/256/RGB colors, bold, italic, underline, strikethrough
  • Streaming-First: Async command handlers with write() and writeln() for AI/LLM output
  • Tiny: ~7KB minified, zero dependencies beyond React
  • Accessible: ARIA live regions, keyboard navigation, screen reader support
  • Command History: Arrow key navigation with deduplication
  • Tab Completion: Auto-complete registered command names
  • Theming: Dark and light themes, fully customizable via CSS

Install

npm install react-termview

Quick Start

import{Terminal}from"react-termview";import"react-termview/styles.css";functionApp(){return(<Terminalcommands={{hello: (args)=>`Hello, ${args[0]||"world"}!`,clear: (_args,terminal)=>terminal.clear(),}}/>);}

Headless Mode

import{useTerminal,Terminal}from"react-termview";import"react-termview/styles.css";functionApp(){constterminal=useTerminal({commands: {greet: (args)=>`Hi ${args[0]}!`,},prompt: "> ",});return(<div><buttononClick={()=>terminal.controls.writeln("System message")}>
Inject Output
</button><Terminalterminal={terminal}/></div>);}

Streaming / AI Mode

<Terminalcommands={{ask: async(args,terminal)=>{terminal.writeln("Thinking...");constresponse=awaitfetchAI(args.join(" "));forawait(constchunkofresponse){terminal.write(chunk);}terminal.writeln("");},}}/>

ANSI Colors

The built-in ANSI parser renders colored text without any extra dependencies:

<Terminalcommands={{status: ()=>"\x1b[32mOK\x1b[0m - All systems operational",error: ()=>"\x1b[1;31mERROR\x1b[0m - Something went wrong",rainbow: ()=>["\x1b[31mR\x1b[33mA\x1b[32mI\x1b[36mN\x1b[34mB\x1b[35mO\x1b[91mW\x1b[0m",].join(""),}}/>

Supported: 16 colors, 256 colors (\x1b[38;5;Nm), RGB (\x1b[38;2;R;G;Bm), bold, dim, italic, underline, strikethrough.

API

<Terminal>

PropTypeDefaultDescription
commandsRecord<string, CommandHandler>{}Command name to handler map
onUnknownCommandCommandHandlerCalled for unregistered commands
initialLinesTerminalLine[][]Lines to display on mount
promptstring"$ "Input prompt string
maxLinesnumber1000Max lines in scrollback
maxHistorynumber100Max command history entries
editablebooleantrueWhether input is enabled
theme"dark" | "light""dark"Color theme
titlestring"Terminal"Title bar text
showTitleBarbooleantrueShow/hide title bar
titleBarReactNodeCustom title bar content
terminalUseTerminalReturnExternal hook instance
classNamestringAdditional CSS class
styleCSSPropertiesInline styles
onLine(line: TerminalLine) => voidCalled when a line is added

useTerminal(options?)

Returns UseTerminalReturn with:

PropertyTypeDescription
linesTerminalLine[]Current terminal output
inputstringCurrent input value
controlsTerminalControlswrite(), writeln(), clear(), focus()
setInput(value: string) => voidSet input programmatically
handleKeyDownKeyboardEventHandlerAttach to input element
suggestionsstring[]Current tab completion suggestions
isStreamingbooleanWhether a command is executing
inputRefRefObject<HTMLInputElement>Ref to the input element

CommandHandler

typeCommandHandler=(args: string[],terminal: TerminalControls,)=>undefined|string|Promise<undefined|string>;

Return a string to output it. Use terminal.write() / terminal.writeln() for streaming.

parseAnsi(text) / stripAnsi(text)

Standalone ANSI parsing utilities:

import{parseAnsi,stripAnsi}from"react-termview";parseAnsi("\x1b[31mred\x1b[0m");// => [{ text: "red", style: { color: "#e74c3c" }}]stripAnsi("\x1b[31mred\x1b[0m");// => "red"

Keyboard Shortcuts

KeyAction
EnterExecute command
ArrowUp/DownNavigate command history
TabAuto-complete command
Ctrl+CCancel current input
Ctrl+LClear terminal
EscapeClose suggestions

Theming

Import the default styles and override with CSS:

.rt-terminal {
font-size:14px;
border-radius:12px;
}
.rt-terminal--dark {
background:#0d1117;
color:#c9d1d9;
}

All classes use the rt- prefix. See styles.css for the full list.

License

MIT

About

Lightweight terminal UI for React with streaming output, ANSI colors, command history, and AI/LLM mode. Headless hook + styled component.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages