I highly recommend Bubbletea. I used it for an internal tool, and it combined with Viper makes an easy-to-use TUI application development easy.
Though it uses an approach more similar to Elm than to React.
I recently used Ink to build a small debugging CLI for a websocket-heavy project of mine. All it does is subscribe to a specific channel and print out the message or send dummy data when I press a specific button. The frontend websocket code could be reused easily so it was very fast to do.
Very convenient to run multiple terminals as multiple clients in parallel. Much nicer at least than something like Postman for Websocket tests.
Full screen took some time to get right and still flickers when using iterm 2. But it does work on the apple terminal and for now I am happy with that.
My only issue is that Ink does not support nested rendering / overlays, i.e. modals.
What role did Ink serve? I mean couldn’t you have just logged to console?
I’m trying to figure out if Ink enabled you to do something at all, made it easier, or you just liked using it. All of which are fair. It seems like you just liked using it.
I think it’s rerendering the “UI” on data updates. Basically exactly the readme for ink. It’s a single log line of output, but it’s repainted in place, not appended to stdout.
Sure you can do that other ways. Personally I’d love to build terminal tuis with react component!
thank you for clarifying. that makes sense and does sound nice to re-render the same line instead of logging a new line each time. I do think it would be simpler/faster (albeit maybe not nicer) to log a message w/ timestamp to accomplish the same thing, putting this in the "nice to have" category.
what the other comment said, it replaces output and looks like a proper terminal UI. But it also adds features for hotkeys, progress bars, text input etc.
I have it integrated into a bigger CLI project where only a few commands enter the UI. Most of them just render to stdout and are meant to be pipeable
I'd be cool to use your approach to build a "frontend" for monitoring Python's TQDM output. Especially useful for multiprocess applications with scores of independent, long running processes like data ingestion pipelines. TQDM does support monitoring multiple processes but is not flexible enough for all use cases.
> I recently used Ink to build a small debugging CLI for a websocket-heavy project of mine.
why not just write tests?
i'm getting super down voted on this, but come on... why? this person built some buggy utility and those bugs can end up causing more problems than just writing tests in the first place.
no wonder we end up with such buggy junk software... people... write tests!
Building a simple debugging tool to monitor your program for possible inconsistently reproducible bugs and having unit tests are not mutually exclusive concept. You're getting downvoted because you're making condescending assumptions about the developer.
I'm not being intentionally condescending. it is a valid question to ask that. i come from a strongly tdd background. i can't tell you how many times i've seen people write simple debugging tools only to have the tool be the source of the bug. ever written a println and output the wrong variable, then scratch your head why the results are wrong?
websockets themselves are well debugged, similar to http. years ago, i stopped spinning up a http server just to test my endpoints. now i just call the functions directly. thus, it would be an issue with the OPs code that is sending/receiving. take websockets out of the equation and everything would work fine with tests.
Friend, we need to be damned careful about how we view others code when they don't have tests or embrace TDD.
When we work with TDD or even a well tested codebase, we do benefit enormously.
We also risk becoming evangelical, and that almost always comes across as condescending and off-putting.
TDD Tests do not capture every possible point of faillure. There's clear use cases for things like Postman, Debugging Proxys, or OPs _debugging_ tool.
PSA - avoid being a hype monger or evangelist of anything, it's about the worst way to support practices or tools you believe in. Trust me, I'm not only a practitioner of TDD but also a Lisp advocate and Emacs user... All these things are the best ever thing that happened /s
No, the whole world won't ever be a place where everyone is "doing it right" by your estimation, or mine, or anyone else's.
Quite the opposite, so settle in and mellow your jets.
>no wonder we end up with such buggy junk software... people... write tests!
absolutely condescending and holier than thou. I view TDD as a premature optimization when writing software that isn't simplistic or cut-and-dry CRUD. Trying to do something new doesn't always mean there's a known output before writing the actual code. Experimentation is a valid thing in software development and writing tests before writing the code would stifle some types of development. In a lot of cases it's bass-ackwards to write tests before the implementation is producing a useful result. I know this type of development might seem foreign to some, but you don't always know what you don't know before you start experimenting while writing code, and TDD doesn't really fit all types of development.
>Writing a tool to inspect websockets, isn't one of them.
That's assuming quite a bit and not at all true in all cases. I deal with websockets with wireless IoT devices and I can tell you that your insistence that debugging websockets doesn't require writing any custom tools is just wrong.
So great, you wrote a test that passes. Your test runs it once. Maybe your test runs it twice. But what happens when the IoT device fails in an unexpected way after the 150th run? Your test isn't going to catch that. If you ran tests repetitively then your test is never going to finish in a reasonable amount of time. Do you think running the tests for an entire day is reasonable? No. That's why sometimes building a "debugging CLI" like OP wrote is needed.
Not everything can always be debugged with a simple test, or any kind of test. Network congestion effects can be tricky to work out. Memory leaks in remote devices you don't control. There's a whole lot of reasons why tests aren't always the catch-all some people think they are. I'm not saying don't write tests, just don't go around suggesting they're a cure-all.
It isn't easy, but all of this can (and should) be tested. It will produce far better and more reliable code. You can certainly run tests 151 times. In fact, if you think you're going to find a bug after that many runs, a test suite is perfect for automating the execution.
Don't believe me? Jespen is a great example of difficult distributed testing done well: https://jepsen.io/
It's definitely captive depending on who leads the team. I've done it before. And it can be abusive if the CTO demands 100% code coverage. It gets to the point where writing any test, even a bad one is better than delaying a release just for the sake of "100% coverage". And that was at an early-stage startup where we had to move fast - and guess what, they went out of business in 6 months because we couldn't get any kind of product out. It was hilariously stupid to demand 100% code coverage on a startup without any product. TDD and testing isn't a cure-all, and in some cases it's a curse.
Your CTO was captive/abusive, not TDD. You're describing your own SS and trying to equate that with "all TDD is bad". I said nothing about 100% test coverage or poor management skills.
In my case, TDD was absolutely the problem with the dev team failing to be able to deliver in a timely way - it wouldn't have matter if the CTO mandated 100% test coverage or 75%. Anyone who thinks TDD doesn't slow a team down to a crawl is just fooling themselves, hence the Stockholm syndrome. In my view, TDD is bad for most projects, but tests are not. TDD is putting the cart before the horse. Tests should be written once the functionality is working well. Then write tests. There are very few kinds of development where TDD is the right way to go, and they involve launching space shuttles, designing medical equipment, and operating nuclear power plants. Launching a social media site? No, just no.
>Writing a tool to inspect websockets, isn't one of them.
What kind of developer makes a blanket statement like that? There are all kinds of situations where debugging is more like detective work. When you discover the problem, then you have the knowledge necessaryto actually write the test that fails and which you can then make succeed.
> What kind of developer makes a blanket statement like that?
One with over 20 years of experience building software used by millions of people daily.
You're trying to generalize a very specific conversation.
OP was talking about building a tool to debug websockets. You don't need to debug websockets, you need to debug your code that is sending and receiving data _over_ websockets. In that case, you don't even need websockets at all. Meaning you don't need a tool to inspect the data either. Just make sure that your code is sending and receiving the correct data and you're done.
Of course, if you want to build a tool, go ahead... that's your choice, but my question is still valid. Why not write tests?
If people don't have the same positive relationship with tests that you do, I could easily see "writing tests" generate enough negative sentiment to seriously degrade a person's capacity engage the near whimsical part of the brain that allows one to think laterally at non-trivial 'distance' from the obvious problem. It could easily be as simple as writing tools is more inspiring / engaging to the OP than writing tests.
I'll chime in here because it looks like you've had a terrible time with someone who's a [insert word of choice].
TDD "evangelism" is often toxic and abusive. The actual practice of a functioning TEAM (not just the devs) who know what it is and how it works, changes things fundamentally for the better.
Spikes are used to do the "whimsical" how the F do we do Y, parts. XP devs don't TDD those and the code is usually tossed out (with the good bits used to help build the production code.)
Similarly TDD isn't a religion, and only an fool would apply it like one. The good parts are, you get a test suite, you get developer examples of how to use a unit, you get an extra step to think about naming, so you're _slightly_ less likely to be saddled with a poorly thought out API / naming scheme.
It's broadly useful, helps teams integrate code, much faster.
Everyone needs to be playing the game, though, and they need to know the rules.
C2 wiki is about the best place to find organic conversations about XP and TDD (archived though, so no sanctimonious claptrap from the likes of me), and the wide internet is a great place to get polarized.
I'm sorry you got a bad taste, and it may have put you off, but a functioning TDD team is about the sanest, quickest, dev team you'll have the pleasure of working with. While, as you've found, an oppressive diktat to DO TDD PROPERLY when the team isn't really doing that, is hellish.
99% of the time, I debug using tests. You write the expected output and then fill in the implementation. If you don't get what you expect, something is wrong with your code and it is easy to run it in the debugger to figure out what is wrong.
At the end of that, you end up with a test and some code that works.
Yeah we all know what you're talking about, you don't have to explain it. Testing is not the universally correct strategy for every case, and unless you take the time to understand their use case, you're really not in a position to understand the tradeoffs or make value statements about their work.
If I had the choice of 'write a tool' or 'write a test'... I'd always pick write a test. Of course, that's me... which is why I asked the question in the first place. I was trying to understand their use case.
Yes. They made their own purpose-built debugger. It's a tool that makes it easier to see what the program is doing. Your debugger is no more or less valid than their debugger. It's a tool, and the best tool is the one that enables the programmer to accomplish their goal. And that's what they did.
most of the time, I write a small amount of code to work through or debug other's code. It's much easier to be consistent and capture more workflow in a script. Later this can be turned into tests or interfaces. Early on, the script offers much better visibility by typically having access to a debugger
I would argue that, based on my experience, most of the code I'm debugging is not my code so it really doesn't matter how many tests I write because the problem is I misunderstood how a library or someone else's code I'm using works or there's a bug I can't find just with tests.
I tried (and sort of failed) to build something like this for rust [0] (warning it's broken at the moment).
It's a lot harder than I expected. Especially since the terminal has no notion of focus, and with Rust it's really hard to not just clone everything you get your hands on when writing a UI library. The borrow checker really feels like it gets in the way of features like signals [1], and partial re-renders.
Very neat idea. I love how decoupled React is from the different renderers, and how well its paradigm of "render a tree of things that updates as state changes" translates to different kinds of UIs
React is indeed really neat. At the same time, however, I miss the visual drag & drop GUI designers that were in vogue a few decades ago. HTML and CSS are the tragedy of modern UI design.
The drag and drop GUI designers used to work because most people were using screens that were approximately the same size and resolution for the most part back then. That is no longer the case today when there is pressure to support everything from a smart watch all the way up to a UHD 4K monitor or TV. Fixed layouts are also much more difficult to localize and translate to other languages than modern layout systems.
Apple's IB used a constraint-based layout by default. It was a fairly novel idea at the time. HTML was ill-suited for that until flexbox/grid came along.
It's one of those "grass is greener on the other side" situations.
I'm currently bouncing back and forth between VB6 and HTML/CSS and yeah sometimes it is nice to just quickly drag something into place, but other times I really wish I could just use a layout system like CSS Grid (or Flexbox) and give it all the items I need and let it figure out how to lay it out.
For instance, recently I had to edit some "tables" in VB6 that turned out to have been hand-drawn with pixel-perfect lines and changes were incredibly slow and I would have murdered for that to be in HTML/CSS.
Sometimes I like (and miss) the best of both worlds in XAML where it has drag-and-drop design tools, but also the copy-and-paste and handwrite support of XML, and it has modern layout tools like Grids for auto-layouts/responsive layouts.
And you can search/diff the pure text representation which is a major plus as well.
I absolutely hate the workflow of constantly moving the mouse back and forth between the visual components and some gigantic property panel sitting at the edge of the window (index-finger programming). Floating windows are even worse, as they always seem to get in the way, so now also spend time on window ceremony (moving / resizing the "floaters").
In graphics tools(InkScape for instance) I almost always move objects around using the cursor keys as my mouse based positioning skills are just not accurate enough (and I know that I'm not the only one)
Anybody have good examples of tools (graphics editors for instance) that has a good alternative to that clunky property pane?
I view the rise of React and especially Electron as the failure of things like GTK, Qt, and e.g. Swing to make a useable cross-platform GUI toolkit that isn't a total nightmare to work with / compile / debug / install / package...it's literally easier to ship [most of] an entire web browser instead. That's insane to me.
I said this before, but here it goes. People always wished for the *one stack that would work the same 99% of the time for all available platforms. Now that it's here, they hate it.
Yes, Electron is bad, but there are alternatives in progress. Layouting with HTML and CSS is here to stay. It's like git, the best of all the worst tools to get the job done.
you can use drag and drop GUI builders on top of react. there's been a lot of attempts at that. a significant recent effort from Wix: https://www.codux.com/
I worked with many different UI kits. From native windows to Ubuntu to automotive to embedded to Android to Apple. I find HTML and css by far the most convenient UI toolkit there is. Never have creating UIs been so easy as with css. A relief it is.
One of my favorite side projects (from several years ago now) was a custom renderer implementation that let one use React to manage the parts of an Electron app outside the page being rendered. [1] I never found the time to actually go through and make it robust enough to use in a production setting, but I remember being very pleased with how much easier it was to use than the native Electron APIs.
This looks amazing. Can anyone talk about the added overhead of this? I'm assuming having to bundle all of Node.js/V8 in your executable is one of them. Plus extra processing to re-render the tree for changes.
I'm wondering if this is worth it to use for very simple CLI scenarios that can be addressed by more lightweight libraries like Cobra. Maybe so your client-side business logic can stay more unified?
It's also really funny to me that what is considered the absolute simplest use case in programming – write a program that outputs a line of text to the console – is still not free from the Node/npm/React experience.
> I'm wondering if this is worth it to use for very simple CLI scenarios that can be addressed by more lightweight libraries like Cobra. Maybe so your client-side business logic can stay more unified?
I'd say yes. Performance will be "good enough". Disk space use or whatever other nonsense HN people love to fret about will be "good enough". And the gains from reusing the same stack everywhere are worth it. I used to think writing little helper scripts in a JVM language (Scala) was an unacceptable overhead, then I realised how low the practical cost was.
> I'm assuming having to bundle all of Node.js/V8 in your executable is one of them
I guess you could expect Linux distros to come with Node (though it's probably a quite dated release). Looking at standalone binaries, both bun.sh and Node.js are about 30MB. In comparison, Python 3.10 is 9MB and starts slower than bun but faster than Node. Bundling is easy too, you can take a loot at vercel/pkg https://github.com/vercel/pkg
You should tree-shake your imports. And in case of Node, it exposes V8 internals to generate bytecode, so you can compile your code - then you don't even need to ship it as text
React kind of reminds me of English. It is ubiquitous for reasons that essentially boil down to imperialism. It imposes at least as many problems as it solves. There is ample evidence that we were getting along fine (if not better) without it. At some point it became the only language many young people know.
And if React is like English, then using it to write a CLI is like using Webster's dictionary to translate hieroglyphs.
That may be but at least for my own case, web development became an order of magnitude more pleasant when React came out. I keep an eye on new frameworks but so far, nothing has caught my attention enough for me to switch.
Yeah, React has always struck me as a bit of a Frankenstein approach to application development. I don't get the appeal, but then I already know how to develop complex applications. If someone can explain if it has any advantage over any native windowing frameworks I'd be interested in reading that.
> Can anyone talk about the added overhead of this? I'm assuming having to bundle all of Node.js/V8 in your executable is one of them.
The primary use case for this would be CLI apps that are already written in JS or TypeScript.
Trying to use this as a front-end for a CLI app written in a different language isn't impossible, but it's a lot of extra work. You'd be better off looking for a similar CLI library in the language you're already using.
Ink is amazing for quickly hacking together TUIs. I recently did so with Nbb (Node Babashka) and and enjoyed the experience overall.
My only real complaint is how everything in your VDOM seems to re-render on a state change. IIRC this is being addressed [1], but is something to be mindful of, especially if your users may be using slow machines.
Yoga is a great choice for layout here. In my own terminal-based projects, I was initially worried that there would be a mismatch between its intended use (pixel-based layout) and the chunkiness of character-based layout in terminal apps, but I was happily proven wrong. Yoga is a great choice for laying out terminal apps.
I wish there was as nice a library for cascading style sheets in terminal apps, but we can't have it all.
Has anyone ever gotten ink to work with OCLIF and TypeScript? I never could figure out how to get those to play nice together. It's ESM only, and that makes things so much harder.
The ESM transition has by far been the biggest pain point of working with JS/TS these last few years.
EDIT: Got it working. Was still a lot more painful than I wish it was. Definitely not converting anything else to use ESM until the landscape here improves.
And then ObjectVision, OWL, and OWLNext. Just don't forget curses or whiptail.
The promises of "easy" and "features" where they don't belong, like using JS and CSS in TUIs is tech debt, security concerns, and resource waste waiting to happen.
Picking on a convenient victim, say Rust, it has: cursive, tuikit, ratatui, and termion that make for powerful, safe, performant, and maintainable code.
It's always cute when absurd things are made possible, but some ideas are impractical for anything beyond toys. If you want toys, sure, do anything and go nuts with it.
Curious to know -- how do these kinds of things affect accessibility for visually impaired people? If you're using a screenreader, do these kinds of things work?
Ink is great to get bare minimums up and running, but the capabilities are quite limited and you can't build full blown interactive dashboards with this like HTOP etc.
I get that such tool needs to exist. In this thread there are a bunch of use cases.
But node feels like it shouldn't be used for CLIs (generic ones, i.e. not tied to a specific language and use case).
Every time I see a tool that seems usefull its a hassle to install the correct node environment for it to work.
I had the idea recently to unify all the rendering code for my cli apps and thought this might be a good approach - I also wanted to allow cli app output to be rendered in the browser.
It wasn't.
I guess it might be good for dynamic apps, but I just love having control over exactly what I a printing out. I'm still looking for a way to write cli apps that also can be accessed from a browser. I always find myself wanting better log viewing functionality - like folding, grouping, search, etc. But there is something so nice about the terminal vs gui. I always avoid gui because the toolchain is horrific and then you have to think about the API layers and everything becomes overly complex and slow.
It might be interesting to see less Flexbox and more CSS Grid support. I think that would make certain styles of TUIs like the Midnight Commander style apps easier to build.
I maintain a library (https://github.com/DioxusLabs/taffy) that implements both Flexbox and CSS Grid and is designed to be easily embedded (similar to Yoga, which Ink is using), if anyone wants add CSS Grid support to their app/framework.
I tried this a long time ago when I was in love with react. It felt difficult to wrap my head around the yoga layout engine. I'm glad others here in this thread seem to like yoga, but I didn't. And, now I really dislike react for various reasons.
I would use this if I needed to write a command line app with nodejs:
I considered blessed for a recent project, but ended up just simplifying the approach & making do with Inquirer + Meow instead due to the maintenance status. Haven't found anything else equivalent to blessed, other than Ink.
I do use emojipedia.org quite often, so I must admit I find this would be quite useful :D. But the thought of having a framework like React powering this behind the scenes, right on my freaking terminal, makes me think that there's no hope for future generations to keep software development simple, "lean" for the foreseeable future. Imagine using 100MB to search for emojis.
cool app, I guess my take is: if the terminal renders react, is my terminal a web browser?. Should I be doing my search in a webbrowser instead? If that's not convenient, why is it not convenient? Should the webbrowser experience be fixed instead of bolting webbrowsing in the terminal?
and yeah i'm aware of lynx
maybe there's some sort of midground where an app is both a display thing and a terminal thing. not sure, but feels like it needs exploring
Pretty neat. I adapted the state management of hooks to Haskell a few years ago. Could be used for similar purposes, but there's no support for templating or styling yet: https://github.com/benweitzman/hooks
this is very good library that i was a little nervous about at first but i used it to build a custom command line tool for my business and it’s helped so much. it’s also very easy to create fancy cli features that make it feel like a real application.
Just what I was looking for, 1000+ JS dependencies and Yoga's deps to make a CLI app. Nope. Hard pass. But, I do love the concept of components for CLIs. I've had much success with the Charm set of tools for CLIs with Go (https://charm.sh).
This seems to be much nicer than ncurses, since it's a declarative interface rather than an imperative one. Outside of Flexbox, there's nothing HMTL-specific in the API. An XML-like syntax is used because UI on most platforms is conceived as an ordered tree structure, such as Windows (XAML), Apple (XIB), Android, and Web (HTML).
The built-in components are all conceived as TTY-native ideas, not as HTML concepts:
Html is not really based on xml, historically its more like the other way around, xml was inspired by html(/sgml). Xhtml was distinct dead-end evolutionary branch
It is true I do not care for xml, html, xhtml or sgml. And the one thing that was decent about sgml, dsssl, we threw away. I do not care for the box model of HTML and would prefer for a segmented flow model so I can easily reason about pages as being... well... pages. I have no problem with declarative layout or semantic documents, but dislike frameworks that conflate the two.
But... clearly... if you like react on HTML and want to have browser-like rendering of text on your terminal than more power to you. I'll go off now and build something that demonstrates my concerns. Thx for not severely down-voting my comment before I could begin to clarify...
The same tired, disparaging comments for anything done in JS get pretty annoying. No, there are not 1000+ dependencies. The entire transitive closure with dev dependencies comes down to 42 dependencies total. Is that a lot? Maybe, but there is value here.
As someone who's authored many CLI tools in the past, libraries like oclif, ink, inquirer, etc were game changers. A little overhead for UX rendering is not material to the performance for many CLI tools. The actual byte streaming/processing and any network calls dwarf the handful of milliseconds you could save by rendering in some more "optimized" way.
Being able to render visualizations, handle user input interactions, and responsively re-render are very useful things.
Is there really a good reason in 2023 to have an interactive command line app? I've seen apps that at least maybe display a web server on localhost and then interact with it through the browser
Or Electron, etc.
I feel like command-line is alienating (deliberately, obviously) a huge portion of potential users. It basically guarantees whatever you made will only get used by tinkerers and not anybody serious (like if I have to pass a proof of concept pet project along to my manager, terminal might make it a non-starter 85% of the time)
Yes definitely. Being able to easily access them via a remote shell is a killer feature IMO. Being able to pipe + automate is useful too if used non-interactively.
I have systems that have no web server and don't need one and adding one would add complexity and potential security risks to the system. Administration is only done via SSH.
There are just situations where the question goes the other way around:
Is there any need for _more_ than a command line interface?
No. Anyone competent enough to do anything meaningful on that server is also capable of doing it via command line.
All of the things you listed are still additional steps compared to just ssh and run the cli tool. Web UIs are nice too, for some things. But for many things, for at lot of us, the cli is where it’s at. And that is where it will continue to be.
We use Web UIs for some things, and cli tools for other things.
From my point of view, I'm not actively making it harder, I just don't make it as simple.
My development process usually starts in the terminal, as I am a terminal user and do iterative development there as well as tinkering with system interfaces.
A CLI is the natural first product of my development. Building a web interface is additional work. Also, it's been a decade since I have written any reasonable web frontend.
Granted, it's not a real TUI with curses and stuff, but I like to do some eye-candy with escape sequences. Because I am the most frequent user of my tools and I always like seeing something I deliberately made look good. :)
Thing is, if you can establish an SSH connection to the target machine, you can easily tunnel HTTP over that. And it doesn't need to have a dedicated web server service for that; the app can embed a localhost-only HTTP server directly.
One could argue that this is extra complexity... but I don't think this argument flies in comparison to "React for CLI", especially once you take into account all the dependencies.
It's largely pointless to forbid it because once you have a byte stream (which you obviously do with ssh), you can tunnel whatever you want over it anyway. SSH own docs even point this out; man sshd_config(5):
"Note that disabling TCP forwarding does not improve security unless users are also denied shell access, as they can always install their own forwarders."
Counterpoint: tinkerers have a lot of overlap with the "serious" users for many CLI apps. People who want no-frills functionality. People who want things to run over N-deep nested SSH hops. Y'know, "unix-y" people (:
I use things like ncdu and vim on remote non-graphical systems all the time, for instance.
Though I do agree that non-interactive is the primary use-case for most CLI stuff.
1. Command line UIs are still an order of magnitude easier to build than even the most basic web page.
2. Every app doesn't have to target every user in the world. There is an entire category of developer-focused tooling that is very suitable for the command line.
3. There are plenty of contexts where the command line is the only interface available.
> Command line UIs are still an order of magnitude easier to build than even the most basic web page.
I think by "interactive command-line apps", parent commenter is talking more about "TUI applications" like e.g. `htop` or `vim`- which are persistent/interactive and treat the terminal as an interactive, 2d canvas into which they render the program content. As opposed to what I'd call "normal" CLI applications, which typically render output and expect user input on a line-by-line basis. (Like most REPLs, or the various ctl programs like `kubectl`, `pgctl`, etc.)
There are no other software products called Firefox (right now). Foxes are not software.
There is Microsoft Windows Ink which does handwriting recognition.
Think about namespaces, in the software namespace, Ink is a loaded term, and most of its use has nothing to do with command-line apps.
This is far closer to a Rust implementation of the readline library. Again, nothing to do with pen recognition software, which is the common use of Ink.
You're intentionally looking for confusion when there is none.
They called it Ink because they considered the terminal is a canvas where you draw stuff. That's it. There's no way anyone will ever confuse a CLI rendering lib with an OCR or a vector graphics editor or whatever.
[1] https://github.com/charmbracelet/bubbletea
[2] https://github.com/textualize/textual
[3] https://github.com/fdehau/tui-rs