
Ink: React for interactive command-line apps - ingve
https://github.com/vadimdemedes/ink#
======
zeptomu
Some time ago I built a (terminal) text editor and one of the challenges is to
implement the renderer which is normally done by messing with termios and
changing some terminal parameters - as this is "device"-dependent there exist
databases like terminfo and abstraction-layers like curses which give you an
API similar to "Write this text at position x/y in green".

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](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.

~~~
thomasballinger
(just to emphasize, I think parent understands this)

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.

------
z1mm32m4n
Surprised to see that this doesn't use ncurses at all. I was really hoping to
see something that brought the painlessness of using React to building an
ncurses textual interface.

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.

~~~
xiaq
If you keep an internal representation of the terminal (which you should
totally do when building a terminal toolkit), you can just update whatever
changed. It is not hard with cursor positioning sequences.

~~~
ams6110
This is what [n]curses does, since decades ago.

~~~
xiaq
Well, my point is that everyone can do this, ncurses is no black magic :)

------
lwansbrough
If anyone is interested in using _actual_ React for the same purposes, check
out react-blessed: [https://github.com/Yomguithereal/react-
blessed](https://github.com/Yomguithereal/react-blessed)

~~~
abritinthebay
Given it’s barely updated and only has official support for React 0.14... it’s
not really something I’d recommend.

Shame too, it has the potential to be great.

~~~
lwansbrough
It not being the latest version if React is hardly a major issue. You miss out
on some of the latest optimizations, but the API hasn't changed.

~~~
dreadpirate15
Which is actually a really good argument for avoiding this project - if it's
so easy to stay compatible, then... stay compatible. Feels like a dead project
if it's so far out of date.

------
fovc
What ever happened to terminal "apps" being streams of text? Is just the JS
ecosystem that does this or are others seeing the same trend?

~~~
scrollaway
vi's initial release date is from 1976. Maybe you could ask someone who used
it back then whatever happened to terminal apps being streams of text? :)

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...

~~~
carussell
I'm hopeful that someone will add a terminal mode interface to VSCode. In
theory, this would allow it to even run without Electron (using just NodeJS).
The team was shrewd enough not to expose too many internals through the
extension interface in the original design, so it's not intractable (at least
not as high up on the scale of intractability as making non-breaking changes
to Firefox).

------
amelius
Would it be possible to write an editor in Ink?

~~~
ignu
Right now, you can't even know the height or width of the terminal. So, I
think you would need to start there.

[https://github.com/vadimdemedes/ink/issues/5](https://github.com/vadimdemedes/ink/issues/5)

------
abdulla
What terminal emulator is being used in that image?

~~~
mofle
Answered in the issue tracker:
[https://github.com/vadimdemedes/ink/issues/10](https://github.com/vadimdemedes/ink/issues/10)

------
GrumpyNl
Nice project but why using REACT for this as REACT is designed for dom
manipulation

~~~
bitwarrior
Well, no it isn't. ReactDOM is designed for consuming the output of React and
constructing a DOM-based UI. React itself is fundamentally a reconciliation
engine. This is why we've seen React move to such places as React Native
(React for native iOS and Android interfaces), React-UMG (React for
constructing interfaces in Unreal Engine's Unreal Motion Graphics), React-PDF
for generating PDFs, the list goes on. You can view more here:

[https://github.com/chentsulin/awesome-react-
renderer](https://github.com/chentsulin/awesome-react-renderer)

~~~
mcphage
> React itself is fundamentally a reconciliation engine.

Do you know of any good articles / books / videos that talk more about this
idea?

~~~
acemarke
Yeah - my React/Redux links list has a big section of articles that talk about
React's implementation, including both articles that dig into the actual React
source and implementation, and many "build-a-mini React" articles:
[https://github.com/markerikson/react-redux-
links/blob/master...](https://github.com/markerikson/react-redux-
links/blob/master/react-implementation.md) .

~~~
mcphage
Thank you!

