Introduction
Overview
What is Terminosaurus?
Terminosaurus is an open-source terminal GUI library that allows you to create terminal applications with ease. It doesn't depend on any specific framework, but provides a powerful React renderer that you can use to create complex terminal applications.
Quick example
Here's a simple example of a Terminosaurus application:
import {StyleValuesconst StyleValues: {
Inherit: symbol;
Length: {
Zero: {
value: number;
isRelative: boolean;
yoga: number;
};
One: {
value: number;
isRelative: boolean;
yoga: number;
};
Auto: {
value: number;
isRelative: boolean;
yoga: number;
};
AutoNaN: {
...;
};
Infinity: {
...;
};
};
... 13 more ...;
WhiteSpace: {
...;
};
}, TermTextclass TermText, lengthfunction length(rawValue: string | number): {
value: number;
isRelative: boolean;
yoga: number;
} | undefined
module length, runfunction run(cb: (screen: TermScreen) => void | undefined): Promise<number> (+1 overload)Create a new TermScreen and run the provided callback. Return a promise that resolves when the screen is closed.} from 'terminosaurus';
runfunction run(cb: (screen: TermScreen) => void | undefined): Promise<number> (+1 overload)Create a new TermScreen and run the provided callback. Return a promise that resolves when the screen is closed.(screenscreen: TermScreen => {
const textconst text: TermText = new TermTextnew TermText(): TermText();
textconst text: TermText.setTextTermText.setText(content: string): void('Hello, world!');
textconst text: TermText.appendToTermNode<TermElement>.appendTo(node: TermElement): void(screenscreen: TermScreen.rootNodeTermScreen.rootNode: TermElement);
textconst text: TermText.styleTermElement.style: Ruleset.resetRuleset.reset: (propertyValues: Map<"flex" | "left" | "right" | "display" | "alignContent" | "alignItems" | "alignSelf" | "flexDirection" | "position" | "inset" | "insetX" | "insetY" | "top" | "bottom" | ... 44 more ... | "pointerEvents", any> | Partial<...>) => boolean({
borderborder?: symbol | string[] | [string | null | undefined] | [string | null | undefined, string | null | undefined] | [string | null | undefined, string | null | undefined, string | null | undefined, string | ... 1 more ... | undefined] | [...] | [...] | undefined: StyleValuesconst StyleValues: {
Inherit: symbol;
Length: {
Zero: {
value: number;
isRelative: boolean;
yoga: number;
};
One: {
value: number;
isRelative: boolean;
yoga: number;
};
Auto: {
value: number;
isRelative: boolean;
yoga: number;
};
AutoNaN: {
...;
};
Infinity: {
...;
};
};
... 13 more ...;
WhiteSpace: {
...;
};
}.Bordertype Border: {
Simple: string[];
Modern: string[];
Strong: string[];
Double: string[];
Block: string[];
Rounded: string[];
}.Moderntype Modern: string[],
paddingpadding?: symbol | [{
value: number;
isRelative: boolean;
yoga: number;
} | {
value: number;
isRelative: boolean;
yoga: string;
} | undefined] | [{
value: number;
isRelative: boolean;
yoga: number;
} | {
value: number;
isRelative: boolean;
yoga: string;
} | undefined, {
value: number;
isRelative: boolean;
yoga: number;
} | ... 1 more ... | undefined] | [...] | undefined: [lengthfunction length(rawValue: string | number): {
value: number;
isRelative: boolean;
yoga: number;
} | undefined(0), lengthfunction length(rawValue: string | number): {
value: number;
isRelative: boolean;
yoga: number;
} | undefined(1)],
fontWeightfontWeight?: symbol | {} | undefined: StyleValuesconst StyleValues: {
Inherit: symbol;
Length: {
Zero: {
value: number;
isRelative: boolean;
yoga: number;
};
One: {
value: number;
isRelative: boolean;
yoga: number;
};
Auto: {
value: number;
isRelative: boolean;
yoga: number;
};
AutoNaN: {
...;
};
Infinity: {
...;
};
};
... 13 more ...;
WhiteSpace: {
...;
};
}.FontWeighttype FontWeight: {
Normal: {};
Light: {};
Bold: {};
}.Boldtype Bold: {},
});
});
And here's the exact same application, but using JSX:
import {renderfunction render(element: React.ReactNode): Promise<void> (+1 overload)Render a React element into the terminal. Return a promise that resolves when the screen is closed.} from 'terminosaurus/react';
renderfunction render(element: React.ReactNode): Promise<void> (+1 overload)Render a React element into the terminal. Return a promise that resolves when the screen is closed.(
<termJSX.IntrinsicElements['term:div']: {
key?: string | undefined;
ref?: React.Ref<TermElement> | undefined;
} & Partial<AllPropertiesInputs> & {
alwaysScrollToBottom?: boolean | undefined;
decorated?: boolean | undefined;
} & AllReactEventsFor<...> & HasChildren:divJSX.IntrinsicElements['term:div']: {
key?: string | undefined;
ref?: React.Ref<TermElement> | undefined;
} & Partial<AllPropertiesInputs> & {
alwaysScrollToBottom?: boolean | undefined;
decorated?: boolean | undefined;
} & AllReactEventsFor<...> & HasChildren borderborder?: "inherit" | "simple" | "strong" | "modern" | {} | [[string | null], [string | null, string | null], [string | null, string | null, string | null, string | null], [...], [...]] | "double" | "block" | "rounded" | undefined={`modern`} paddingpadding?: "inherit" | {} | [[string | number], [string | number, string | number], [string | number, string | number, string | number, string | number]] | undefined={[0, 1]} fontWeightfontWeight?: "inherit" | "bold" | "normal" | "light" | undefined={`bold`}>
Hello, world!
</termJSX.IntrinsicElements['term:div']: {
key?: string | undefined;
ref?: React.Ref<TermElement> | undefined;
} & Partial<AllPropertiesInputs> & {
alwaysScrollToBottom?: boolean | undefined;
decorated?: boolean | undefined;
} & AllReactEventsFor<...> & HasChildren:divJSX.IntrinsicElements['term:div']: {
key?: string | undefined;
ref?: React.Ref<TermElement> | undefined;
} & Partial<AllPropertiesInputs> & {
alwaysScrollToBottom?: boolean | undefined;
decorated?: boolean | undefined;
} & AllReactEventsFor<...> & HasChildren>
);
Comparison table
| Feature | Terminosaurus | Ink | Blessed |
|---|---|---|---|
| Framework-agnostic API | ✅ | ❌ | ❌ |
| React renderer | ✅ | ✅ | ⚠️ ¹ |
| Flexbox layout | ✅ | ✅ | ❌ |
| Relative / absolute positioning | ✅ | ❌ | ❌ |
| Focus management | ✅ | ✅ | ❌ |
| Scrolling | ✅ | ❌ | ❌ |
| Text alignment | ✅ | ❌ | ❌ |
| Text wrapping | ✅ | ❌ | ❌ |
| CSS properties | ✅ | ✅ ² | ❌ |
¹ Blessed kinda supports React 17 thanks to react-blessed, but it's unmaintained.
² Ink also supports some CSS properties, but not as much as Terminosaurus.