████████╗███████╗██████╗ ███╗ ███╗██╗███╗ ██╗██╗ ██╗███████╗ ╚══██╔══╝██╔════╝██╔══██╗████╗ ████║██║████╗ ██║██║ ██║██╔════╝ ██║ █████╗ ██████╔╝██╔████╔██║██║██╔██╗ ██║██║ ██║███████╗ ██║ ██╔══╝ ██╔══██╗██║╚██╔╝██║██║██║╚██╗██║██║ ██║╚════██║ ██║ ███████╗██║ ██║██║ ╚═╝ ██║██║██║ ╚████║╚██████╔╝███████║ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝
A React-inspired TUI framework for Java 21
Component. Leaf nodes render; Containers hold children.
Build a Layout, add components, call TerminusApp.run().
Raw mode, the event loop, diff rendering — all handled for you.
No boilerplate, no lifecycle annotations, no XML.
// imports omitted public class App { public static void main(String[] args) { Layout root = Layout.column().padding(1).build(); root.add(Text.bold("My App", 0x7F77DD)); root.addFlex(Table.builder(model, columns).build()); root.add(statusBar); TerminusApp.run(root); } }
Component (abstract) ├── Leaf // renders directly │ ├── Text │ ├── ProgressBar │ ├── TextInput │ ├── Table │ └── [your component] └── Container └── Layout (row | column) └── gap · padding · flex
Wrap, align, truncate, color. Word wrap with max-lines and ellipsis. The atom of every layout.
Four styles — eighths Unicode, solid block, ASCII, and braille. All animate at 60fps.
Cursor, history, selection, kill rings. Ctrl+K, Ctrl+U, word-jump, SGR-bracketed paste.
100k+ rows. Virtual scroll. Sortable columns. Typed model. Selection callbacks.
| ↑ ↓ | move selection |
| Home / End | first / last row |
| Page Up / Down | scroll by page |
| s | cycle sort column |
| S | reverse sort direction |
| r | reset to original order |
| Enter | fire onSelect callback |
render() is pure. State mutations live in onEvent(). Unidirectional data flow.
| Pattern | Where |
|---|---|
| Composite | Component / Container / Leaf |
| Visitor | Renderer walking the tree |
| Chain of Responsibility | EventDispatcher |
| Observer | markDirty() bubbling |
| Builder | Every component API |
| Template Method | LayoutEngine |
| Strategy | FlexConfig, TableModel |
| Pattern | Where |
|---|---|
| Command | Event sealed hierarchy |
| Double Buffer | ScreenBuffer |
| Repository | TableModel |
| Facade | TerminusApp, RenderPipeline |
| State Machine | KeyParser |
| Value Object | Cell, Bounds, Constraint |
Add terminus-core to your build. No annotation processors,
no code generation, no configuration files. Just components.
dependencies { implementation 'io.terminus:terminus-core:1.0.0' }
<dependency> <groupId>io.terminus</groupId> <artifactId>terminus-core</artifactId> <version>1.0.0</version> </dependency>
$ git clone https://github.com/P0intMaN/terminus.git $ cd terminus $ ./gradlew :terminus-demo:shadowJar $ ./run-demo.sh # a real terminal — not via gradle