@react-tela/terminal
v2.0.0
Published
A [react-tela](https://github.com/TooTallNate/react-tela) component that renders a terminal emulator on a Canvas2D surface using [xterm.js](https://xtermjs.org/) (headless).
Readme
@react-tela/terminal
A react-tela component that renders a terminal emulator on a Canvas2D surface using xterm.js (headless).
Features
- 🖥️ Full terminal emulation via
@xterm/headless - 🎨 ANSI 256-color support
- ✨ Inherits all react-tela entity props:
alpha,rotate,scaleX/Y,shadow,filter,blendMode - 📐 Auto-calculates
cols/rowsfrom dimensions, or set them explicitly - 🔄 Dynamic resizing — adapts when width/height change (e.g. inside
<Flex>) - ⌨️ Async
write()that resolves when xterm has processed the data
Usage
import React, { useEffect, useRef } from "react";
import { Terminal, TerminalEntity } from "./src/index.js";
export function App() {
const ref = useRef<TerminalEntity>(null);
useEffect(() => {
const term = ref.current;
if (!term) return;
term.write("Hello, terminal!\r\n");
term.write("\x1b[32mGreen text\x1b[0m ");
term.write("\x1b[31mRed text\x1b[0m ");
term.write("\x1b[34mBlue text\x1b[0m\r\n");
term.write("\x1b[1mBold\x1b[0m \x1b[4mUnderline\x1b[0m \x1b[7mInverse\x1b[0m\r\n");
term.write("\x1b[?25l"); // hide cursor
}, []);
return (
<Terminal
ref={ref}
fontSize={14}
fontFamily="Geist Mono"
theme={{ background: "#1e1e1e", foreground: "#d4d4d4", cursor: "transparent" }}
/>
);
}
ANSI Colors
The terminal supports the full ANSI 256-color palette:
import React, { useEffect, useRef } from "react";
import { Terminal, TerminalEntity } from "./src/index.js";
export function App() {
const ref = useRef<TerminalEntity>(null);
useEffect(() => {
const term = ref.current;
if (!term) return;
term.write("\x1b[1m Standard Colors \x1b[0m\r\n");
for (let i = 0; i < 8; i++) {
term.write(`\x1b[48;5;${i}m \x1b[0m`);
}
term.write("\r\n");
for (let i = 8; i < 16; i++) {
term.write(`\x1b[48;5;${i}m \x1b[0m`);
}
term.write("\r\n\r\n\x1b[1m 216 Colors \x1b[0m\r\n");
for (let i = 16; i < 232; i++) {
term.write(`\x1b[48;5;${i}m \x1b[0m`);
if ((i - 15) % 36 === 0) term.write("\r\n");
}
term.write("\r\n\x1b[1m Grayscale \x1b[0m\r\n");
for (let i = 232; i < 256; i++) {
term.write(`\x1b[48;5;${i}m \x1b[0m`);
}
term.write("\r\n");
term.write("\x1b[?25l"); // hide cursor
}, []);
return (
<Terminal
ref={ref}
fontSize={14}
fontFamily="Geist Mono"
theme={{ background: "#1a1a2e", foreground: "#eee", cursor: "transparent" }}
/>
);
}
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| cols | number | Auto from width | Number of columns |
| rows | number | Auto from height | Number of rows |
| fontSize | number | 16 | Font size in pixels |
| fontFamily | string | "monospace" | Font family |
| charWidth | number | Auto | Character width in pixels |
| lineHeight | number | Auto | Line height in pixels |
| theme | ITheme | {} | xterm.js theme object |
| scrollback | number | 500 | Scrollback buffer size |
| scrollOffset | number | 0 | Rows scrolled back from the bottom. 0 = latest content. Positive values scroll up into history. Clamped to available scrollback. |
| onData | (data: string) => void | — | Terminal output data callback |
| onResize | (cols: number, rows: number) => void | — | Resize callback |
Plus all standard react-tela entity props (x, y, width, height, alpha, rotate, etc.).
Scrollback
The terminal maintains a scrollback buffer (default 500 lines). Use the scrollOffset prop to scroll up into history:
// Show content 10 rows back from the bottom
<Terminal ref={ref} scrollOffset={10} />
// Or set it imperatively
ref.current.scrollOffset = 10;
// Back to latest
ref.current.scrollOffset = 0;The offset is clamped to the available scrollback — you can't scroll past the beginning of the buffer. The cursor is hidden when scrolled back. The viewport size stays the same; only which rows are displayed changes.
Ref Methods
Access the terminal entity via ref:
const ref = useRef<TerminalEntity>(null);
// Write data (async — resolves when processed)
await ref.current.write('Hello\r\n');
// Access the underlying xterm.js instance
ref.current.terminal.scrollToBottom();Installation
npm install @react-tela/terminal react-telaLicense
MIT
