jatatui 0.30.0 — first release
jatatui is here: a complete Java port of ratatui v0.30.0, with a brand-new React-style component layer on top. Build rich terminal UIs from idiomatic modern Java — records, sealed interfaces, switch expressions, all the good stuff.
This is the successor to tui-scala (which ported the much older 2022-era tui-rs). Same heritage, fresh codebase, current upstream.
What you get
The faithful core
A complete port of ratatui's split-workspace 0.30 release:
crossterm— JNI binding to crossterm-rs, with native libraries for 5 platforms baked into the jar: Linux x86_64 / aarch64, macOS x86_64 / arm64, Windows x86_64. No external native deps.jatatui-core— Buffer, Cell, Style, Color, Modifier, Layout, Constraint, Rect, Frame, Terminal, Text/Line/Span.jatatui-widgets— Block, Paragraph, List, Table, Tabs, BarChart, Chart, Calendar, Canvas, Gauge, Sparkline, Scrollbar, Clear, JatatuiLogo, JatatuiMascot, TextInput.jatatui-crossterm—CrosstermBackendand the Color/Style/Modifier conversion glue.
If you've used ratatui in Rust, the model carries over directly. No learning curve beyond Java syntax.
The React-style layer (the new shiny)
jatatui-react and jatatui-components add a React-shaped API on top of the buffer:
- Components as functions with hook-based state —
useState,useRef,useEffect,useFocus,useContext,useTimeout. - Fiber-based reconciliation — when a component's type changes at a slot (e.g. router screen swap), hook state under it is dropped. No state-bleed across screens.
- Focus management — imperative (
ctx.focus(id)/ctx.blur()), eager auto-focus claim on mount, focused-chain event bubbling withstopPropagation. - Portals for modals, dropdowns, tooltips. Pair with
Clearfor opaque overlays. - Two entry points —
ReactApp.run(...)for turnkey apps,Rendererfor embedding into an existing draw loop. - Higher-level components ready to drop in — text input, dropdown, picker (search + ranked list), selectable list, button, screen frame, confirm dialog, link, scrollable, list/table/gauges, toasts provider, form provider, router, theme provider, IntelliJ-style fuzzy match.
Take a look:
import static jatatui.react.Components.*;
import jatatui.core.style.Color;
import jatatui.core.style.Style;
import jatatui.react.ReactApp;
import jatatui.widgets.Borders;
import java.util.Optional;
import tui.crossterm.KeyCode;
public class Counter {
public static void main(String[] args) throws java.io.IOException {
ReactApp.run(component(ctx -> {
var count = ctx.useState(() -> 0);
boolean focused = ctx.useFocus(Optional.of("counter"), true);
if (focused) {
ctx.onKey(new KeyCode.Up(), () -> count.update(n -> n + 1));
ctx.onKey(new KeyCode.Down(), () -> count.update(n -> n - 1));
}
return box(
focused ? " Counter * " : " Counter ",
Borders.ALL,
text("Count: " + count.get(),
Style.empty().withFg(focused ? Color.YELLOW : Color.CYAN)),
row(
button("[ + ]", Style.empty().withFg(Color.GREEN), () -> count.update(n -> n + 1)),
button("[ - ]", Style.empty().withFg(Color.RED), () -> count.update(n -> n - 1))));
}));
}
}The React layer is proof-of-concept: it has been used to build a real app and the core ideas are working, but expect API churn as it matures. Pin a specific version if you depend on it.
Install
Coordinates: com.olvind.jatatui.
<dependency>
<groupId>com.olvind.jatatui</groupId>
<artifactId>jatatui-core</artifactId>
<version>0.30.0</version>
</dependency>
<dependency>
<groupId>com.olvind.jatatui</groupId>
<artifactId>jatatui-widgets</artifactId>
<version>0.30.0</version>
</dependency>
<dependency>
<groupId>com.olvind.jatatui</groupId>
<artifactId>jatatui-crossterm</artifactId>
<version>0.30.0</version>
</dependency>Add jatatui-react and jatatui-components (same coordinates) if you want the React layer.
JVM target is Java 21.
Try the demos
git clone https://github.com/oyvindberg/jatatui
cd jatatui
bleep run jatatui-demo -- demo2 # ratatui examples/apps/*
bleep run jatatui-demo-react -- counter # React-layer playgroundThanks
Massive thanks to the ratatui maintainers for the original library, the upstream rewrite, and the steady release cadence that this port chases.
Full Changelog: https://github.com/oyvindberg/jatatui/commits/v0.30.0