Ink: React for interactive command-line apps
github.com
github.com
However curses and terminfo are big programs and most terminals they support are not in use anymore, so if one is OK with supporting just 99.9 (and not 99.999 like curses)% of modern terminals (say xterm, linux-console, st, urxvt, $otherterm), it is feasible to roll your own or use an alternative like e.g. termbox (https://github.com/nsf/termbox).
It provides a simple API like "write Unicode-Char to position x/y in specific $style" and some utility functions to setup the terminal (e.g. one has to consider how to react to window-size (== terminal rows/cols size) events). You can then write your app similar to a game-loop like the following:
while state['should_run']:
render(state)
update(state)
get_input(state)
I think such an API is pretty nice to work with - this is different to the React approach, but for writing terminal GUIs like text editors it worked pretty well for me.Many (native) games use a similar approach when rendering menu's and stuff and although there are terrible ones most menus of games look pretty slick.
The render function here can be stateful, React vdom-style: diff with previous output, efficiently update output based on the perf characteristics of a terminal. But it's an entirely separate domain, which is great for the developer.
Seeing that it doesn't use ncurses, I'm suspicious of how it does re-draws. I'd imagine the naive thing of just redrawing every bit of text on the screen for every reactive event would work, but be pretty slow. Of course, if they're doing something smarter than this, I'd be interested to hear how it's done.
This library looks real neat, a declarative TUI with an api already familiar to many developers. I've thought this would be a neat thing to exist since I started using React after having written a similar declarative, redraw-only-as-necessary terminal rendering library for bpython (http://ballingt.com/bpython-curtsies/).
In it (http://curtsies.readthedocs.io/en/latest/) the only rendering optimization was a line cache. For the specific use case of an interactive interpreter this worked pretty well: once a line is changing, it's probably changing a lot. But you could go further using the output of diffing of arrays of terminal text.
edit: whoa https://github.com/Yomguithereal/react-blessed looks awesome for this
Shame too, it has the potential to be great.
This is an interesting idea; a React-like layer to something like ncurses could be super useful and encourage more command line apps. Doing this in JS seems like a waste though...
Solid and proven and robust, yes.
Different things however.
Seems like a pretty easy switch.
The best part about React is being able to declare what your UI will look like instead of constructing it. It's a useful abstraction for any dynamic UI.
It's not using React. "X for Y" is an analogy, as in "it's like React, but for CLI apps!"
Do you know of any good articles / books / videos that talk more about this idea?
We use React at Netflix for building our TV app. We moved away from a WebKit stack a few years ago; we have our own retained-mode graphics engine optimized for TV devices so we created React-Gibbon. Besides the developer ergonomics stemming from React, we like the approach it affords us for reaching low-performing devices.
At Airbnb we built a renderer for Sketch that allows us to generate templates for designers with our real, cross-platform, production components (built with React Primitives) https://github.com/airbnb/react-sketchapp