cloudterm
v0.0.15
Published
Tiny DOM-rendered terminal emulator for the web.
Maintainers
Readme
cloudterm
Tiny DOM-rendered terminal emulator for the web.
Live demo and benchmarks: termlab.coey.dev
Quick start
Install the package:
npm i cloudterm
# bun add cloudterm
# pnpm add cloudtermCreate a host with an explicit size in index.html:
<div id="terminal" style="width: 800px; height: 400px"></div>
<script type="module" src="/main.js"></script>Then put this in main.js:
import { mount } from 'cloudterm';
import 'cloudterm/style.css';
const decoder = new TextDecoder();
const el = document.getElementById('terminal');
if (!el) throw new Error('missing #terminal element');
const term = await mount(el, {
onData(bytes) {
const text = decoder.decode(bytes);
console.log('send input to your server:', text);
},
});
term.write('cloudterm is ready\r\n');
term.focus();The CSS import and a measurable host element are required. onData receives a Uint8Array; decode it before sending text to a transport. This is everything needed for an embed; full types are below.
Why
cloudterm renders selectable terminal text in the DOM and leaves the transport to your application. It has one runtime dependency and no framework wrapper.
Properties
| | |
|---|---|
| Renderer | DOM text with virtualized visible lines |
| Dependencies | 1 (@chenglou/pretext) |
| Bundle | 48,483 bytes raw, 14,335 bytes gzip |
| License | MIT |
How it works
Call write with server output. cloudterm parses terminal escapes and paints the visible grid in the host element. Keyboard and paste input arrive at onData as bytes for your transport to send; call focus after mounting when the terminal should accept input.
API
interface Theme {
background: string;
foreground: string;
cursor: string;
fontFamily: string;
fontSize: number;
}
interface SearchOptions {
caseSensitive?: boolean;
regex?: boolean;
}
interface SearchMatch {
line: number;
col: number;
length: number;
}
interface MountOptions {
onData: (data: Uint8Array) => void;
onResize?: (cols: number, rows: number) => void;
onTitle?: (title: string) => void;
onCwd?: (uri: string) => void;
onClipboard?: (text: string, selection: string) => void;
theme?: Partial<Theme>;
maxScrollback?: number;
predictionMode?: 'off' | 'auto';
}
interface Terminal {
write(data: string | Uint8Array): void;
fit(): void;
focus(): void;
destroy(): void;
search(query: string, opts?: SearchOptions): SearchMatch[];
findNext(query: string, opts?: SearchOptions): SearchMatch | null;
findPrevious(query: string, opts?: SearchOptions): SearchMatch | null;
clearSearch(): void;
serialize(): string;
restore(data: string): void;
readonly cols: number;
readonly rows: number;
}
declare function mount(el: HTMLElement, opts: MountOptions): Promise<Terminal>;
export { MountOptions, type SearchMatch, type SearchOptions, Terminal, type Theme, mount };Theme.background,foreground,cursor,fontFamily, andfontSizeset terminal appearance.SearchOptions.caseSensitivematches letter case;regextreats the query as a regular expression.SearchMatch.line,col, andlengthlocate one search result.MountOptions.onDatareceives terminal input bytes.onResizereceives the measured column and row count.onTitlereceives OSC window-title changes.onCwdreceives OSC current-working-directory URIs.onClipboardreceives OSC clipboard text and its selection name.themeoverrides theme values;maxScrollbacklimits retained lines;predictionModeis'off'or'auto'.Terminal.writedisplays text or bytes;fitrecomputes dimensions;focusfocuses input;destroyremoves the terminal.search,findNext,findPrevious, andclearSearchmanage search results.serializesaves state andrestoreloads it.colsandrowsare the current measured dimensions.mountwaits for the host to be measurable and returns a terminal.
Theme via CSS variables
.cloudterm {
--ct-bg: #111;
--ct-fg: #eee;
--ct-cursor: #4ade80;
--ct-font: 'JetBrains Mono', monospace;
--ct-font-size: 14px;
}Not included
- A shell, PTY, or WebSocket transport
- Framework wrappers or addons
- Canvas or WebGL rendering
Development
bun install
bun run build
bun run size
bun run check:readme
bun testLicense
MIT. See LICENSE for xterm.js attribution on the ported keyboard module.
