I am working on a new python project and one of the first things I added was https://github.com/Textualize/rich because of how easy it is to make things look good in the terminal.
I love building command line tools and as much as I like the look of Textual I've tried it a few times and it's a little too heavy/inflexible for me. Rich on the other hand is immense and I makes development so smooth- it's great to be able to have a nice api for bold/color/emoji/tables etc straight out the box!
I haven’t used textual so I’m not sure if these are exactly the same type of thing, but for Go clis it is worth checking out the libraries that the folks at https://charm.sh/ have created.
In the past I used lanterna (https://github.com/mabe02/lanterna/tree/master) to develop a text UI for a critical process at the trading firm I worked at. It was essentially a process that would take updated market data and handle things that changed between the last trading session and today - like symbol renames (PCLN to BKNG), changes to market cap that make it change what "category" it fell into (they were based on market cap and volatility measures etc). Things of that nature, that the realtime system didn't handle but happened too often or were too hairy for us to just handle manually.
The system had a desktop UI component that was oriented towards use by our trading staff. We didn't really have notion of a "server UI" and the server was headless.
Nobody at our firm was a frontend developer, just backend, systems and data programmers who occasionally dabbled in frontend. So web UIs were very simplistic or highly specific to their use-case, we had no shared tooling.
In 2023 with things like create-react-app and whatever next.js does, I probably would've opted for one of those. I could've made another desktop app but I wanted to be able to easily get to this from a shitty ssh connection over tethered 4g when I was on-call. So X11 forwarding and RDP were out. So i looked around for a TUI-builder in the project's language, Java.
What i really liked about Lanterna was that it had a Swing-based implementation which meant I could easily run it from IntelliJ, and that would let me iterate rapidly, and then in production I could run it in a terminal via SSH directly on the machine the server was on (which had certain advantages).
I'll keep an eye on this to see if I can think of anything neat to build on it. I still generally don't like web apps because they feel like they take a lot of effort to get something compared to a functionally-equivalent product built in something non-browser-based like a TUI or desktop GUI.
Unfortunately, the "Rapid Application Development" thing also seems to apply to the library itself: you get a new release every other week, and stuff breaks in somewhat unpredictable places. So it's easy to prototype something with Textual, but hard to maintain it afterwards.
I get that this can be annoying (as someone who maintains code written using Textual, I very much get it), but while we're still 0.x we are making the most of being able to steer in slightly different directions if a more beneficial approach becomes obvious in some area.
We also try really hard to highlight breaking changes when a new release is made.
And, of course, if anything particular is tricky to work around or get working again anyone is welcome to seek some help in GitHub issues, discussions or even on Discord if that's your thing.
Looks amazing! Not a seasoned Python developer, so I ask how easy it is to build a binary from this without any (major) dependencies?
I’m looking for something that helps me build installation packages of my product for Windows and Linux. There are a set of configurations that must be done before and after my customers install my software - write to INI files, check db connection, check http servers and so on.
This looks great. I just finished an internal devops and change control app using unicurses and python and although it works, it will not scale well. Initially, I tried doing TK and QT but they both have their quirks with initial installation. My experience with QT is that its works well but useful documentation is sparse.
I'll definitely be giving textual a try as it fits my requirement space perfectly.
...what have people had success with in golang-world? Anything reasonably equivalent someone could recommend? There's a fair amount of "stuff" for TUI's in golang, the thing that's very attractive about 'textualize' is it feels very "web-browser-y" and has a nice (scrollable!) table view.
`tview` seems interesting (eg: check `brew install dbui`), but feels a bit more like _you're_ doing all the imperative `if KeyPress.A: do_something()` instead of declarative, nesting navigation, etc. (perhaps that's the difference between an "application-centric/SPA" view of "control all the things!" vs. a document centric: "add components to a page and let them flow").
More like the generally accepted concepts of "selected, active, focus, style, change", and declaring either a visual response or "onEvent" response.
A nested hierarchy, components may be complicated internally but expose a simple input and output interface.
And yes, something a little more high level than `if key == 'a'` means you're focusing more on the data and display rather than the method. Different abstractions for different use cases, I guess.
But seriously, check out their "easing" and transition stuff. The 500ms "lag" is annoying for power users, but does help provide context while learning an app's navigation I guess?
Question: How do projects like these sustain themselves? This project is being developed from 2 years and I see no sources of revenue. Do the developers get any form of compensation for creating this?
I was looking for a python graphical interface library and came across this, I came to the conclusion that it is way too resource greedy and anything you build with it will be heavy.
This can't be serious. The number of resources being consumed by web frameworks is absolutely insane, they are built on so many layers. .NET desktop apps the same thing. You need a full windows install, then graphics drivers, then the .NET framework stuff.
This is running in a terminal. The golang tui's are tiny by comparison to apps like office etc and can deploy in much smaller total footprints.
I would love to find a way to get some sort of emulation layer to get Textual apps running in the browser. Does anyone know of any projects that might aid in this silly goal?
I'm imagining a workflow where textual can be used as a progressive enhancement for a cli tool, in case the user doesn't pass in all required flags. A web frontend for that view will make it more comfortable for even more types of users.... :)
python code_format.py --file app.js => textual isn't used/invoked at all
python code_format.py => textual is used to show user a DirectoryTree file dialog, then exits
I'm assuming this could work via "App" return values: app.exit({ file: "app.js" })
Do you have any examples of textual being used in this manner? If not, no worries
I don't understand this view. I used vscode and the amount of customization I had to do, per project was equal or greater then what I have to do with neovim. Do you never change anything or have to fiddle with extensions to get the desired behavior? Or creating run configurations for projects?
After a few decades of developing applications, I am convinced that frameworks are the wrong approach.
You gain development speed in the beginning, but you lose it later on when the framework introduces breaking changes and you have to keep working around a changing stack. Or the framework gets abandoned and it would be too much work to maintain it. Because it has so much bells and whistles you don't need. This one for example contains 1298 files without dependencies.
Both, coding everything yourself or using lean libraries are better. There are very few lean libraries unfortunately. Keeping code elegant and simple is a rare skill.
When there is a lean, well done library for my use case, I use it. Because if shit hits the fan, I can maintain the library myself.
> There are very few lean libraries unfortunately. Keeping code elegant and simple is a rare skill.
So... You are saying 'you should write everything yourself with libraries that basically don't exist'? I agree with you somewhat, but it's not very realistic; it's so much faster to use something that gets you 80% of the way with minimum work. And you know it'll break in a bit but that's life.
Also, frameworks like Django or ASP.NET have been pretty stable for a very long time. We have large Django projects from 10 years and updating those was a breeze.
It is totally realistic. I have multiple projects running that do not use any external code. With millions of users.
Those projects are PHP though. PHP has a lot of bells and whistles on board. Unfortunately with PHP 8, they started introducing a lot of breaking changes. So they lost my trust and I will use Python for new projects.
Not sure yet if I will use Django (As you said, it seems pretty stable) or do the good old CGI approach. If I do the latter, I will probably write a new CGI library for it, because in the Python ecosystem it is all about long running processes nowadays and I think that is the wrong approach.
Long-running processes have their uses but they are not the only tool or the end of the evolution. "Serverless lambda" is one example of how moving back to one-off processes provides a different kind of value.
The >1 second time was for a very unusual circumstance. Unless you timed PHP startup time using straight CGI (not mod_cgi, nor FastCGI) on a Lustre file system about 15 years ago, with the appropriate set of extensions enabled for what our application needed, you can't really compare the two.
"By default, PHP is built as both a CLI and CGI program, which can be used for CGI processing. If you are running a web server that PHP has module support for, you should generally go for that solution for performance reasons."
It's been a while since I've seen anyone brag about PHP's speed.
PHP is quite slow at encoding and decoding JSON, very slow at any kind of tree data structure, and has among the highest memory usage of any language at printing a string of text to a console or otherwise.
Python is faster at all of those things and it's quite slow. Those are kind of web related tasks, and the web benchmarks for say django vs laravel don't show that PHP is any kind of winner.
My bigger issue with the CGI model is the lack of handling connections as streaming. You can't parse a file while it's still being uploaded, and that can eat up a lot of memory on larger files.
I know startup times can take a toll like establishing db connections, cache checking (like redis), file imports, etc. If you are using something that starts up for every request, then you have to be aware of those kinds of things and design around them.
By the time everything is imported and running you can be into the territory of really not wanting to do it on every request. I’ve not timed it in my case for a while but you’re definitely looking at 100s or 1000s of ms.
Long running processes only need to load their imports, configuration, database connections, etc. once, and don't incur overhead for each request. On top of this, things like imports get to be cached, and there's less need for a database connection pooler to broker connections.
Particularly async runtimes have become more popular - where you can have a single process handling concurrent requests and awaiting/yielding in between their api/db calls. Instead of having many processes that don't share resources that might be waiting 10ms/100ms for api/db calls.
For applications that make large numbers of api/db calls - especially slower ones, may prefer async runtimes over individual processes per request.
I'm not at all saying CGI is a bad option, just that there are real benefits to reusing, pooling and caching resources.
I think this really depends on the kind of applications you’re developing, and how you use frameworks during the development process.
Frameworks really shine at quickly proving out concepts. They enable prototypes that would have otherwise been too costly to produce, which is often the difference between a project moving forward or not.
The problem is often what comes next: teams fall for the productivity boost and carry the rapid design forward expecting similar gains throughout the rest of the project.
I use frameworks when I want to get ideas out of my head. I tend to throw framework code away if I take the project further, and I’m in a better position to implement from scratch knowing what I’d do differently.
YMMV, the environment you work in makes a big difference, the kind of thing you’re building makes a big difference, etc.
this is developer's gospel for me
So I don't have to always to use the framework's feature all the time ??!!!
When I face an issue with the framework, I tend to question my ability as a programmer, even though i could code it myself.
Like a non trivial django form, I could have just manually coded the form, then just pass the data to the view, validate it manually. Instead of fighting
You could also just use some known, boring technology. I was using Java Swing in 2016. It was rock-solid and unchanging. It will outlive me. Nobody is going to touch it again (all the churn is now in JavaFX). And yet! It even got HiDPI support somewhere around Java 8 or 9 (or at least, whatever they did, Swing apps now respect display scaling when at one point they definitely did not).
Frameworks exist, because you can't code everything yourself. And libs are pointless if you need interconnected gears, which UIs are very heavy users of. Frameworks exist, and remain to exist, because there is demand and they solve problems. But yes, not every framework is good.
I really want to agree with this, but the trouble is that an unstated prerequisite is that you need a team of developers that have a strong sense of software design. A sensibility I've come to believe is drastically in decline in more junior software engineers (though don't mistake this for a statement that the quality of these devs appears any less).
Just take Ruby on Rails, which is probably a great example of a framework that runs into the problems you're describing. My experience with more contemporary, generally more junior, dev teams is that the "Rails" part of the framework is essential for these developers to maintain any loose semblance of adherence to any kind of architecture or design principles.
Earlier in my career I remember, even junior devs, spending a fair amount of time thinking about about the abstractions they were using, making design decisions, and often times being more guilty than not of over thinking abstractions.
Today I've seen so many very bright and talented engineers whose sole view of good software is minimizing the time from request to PR (and code reviews that strong favor minimizing the time from PR -> prod).
If you have a bunch of senior engineers (not SV "senior", but truly experienced), and they're the type that still pick up SICP form time to time, or spend a Saturday reading a section of TAOCP, then sure I think the framework-free approach is best. But you also don't need to tell that to a team of engineers like that.
Otherwise, frameworks and even languages that do the most handholding when it comes to design decisions are going to remain essential.
what’s with the jab about SV “senior”? where i am, senior engineers are properly senior. and nobody even knows what levels and titles people have. ¯\_(ツ)_/¯
If your app lives in a vacuum I don't see why you'd ever need to upgrade the framework.
If it doesn't then the code you wrote yourself will eventually break as the rest of the world advances their APIs and standards.
Even a website written in pure HTML and put up on a small linux server a decade ago would have rendering issues as well as probably not allowed past browsers or corporate firewalls due to older SSL libraries.
> If your app lives in a vacuum I don't see why you'd ever need to upgrade the framework.
Unfortunately the only apps that live in a vacuum are embedded apps not connected to the internet. We should all be monitoring our dependencies for security upgrades. Eventually even a stable framework like Django goes out of long term support. I wrote a Django app in 2008 that is still in heavy use today and at some point had to go through and upgrade to a new major version. It wasn’t a breeze, it took me a few weeks. To leave the app live on that 10 year old version would have been irresponsible for security reasons. The only apps that live in a vacuum are embedded apps, like the one in a vacuum cleaner.
The vacuum gets power from an electrical network that is also fully capable of transferring structured digital information as well. My point is that your own code will also break if you don't keep it maintained for all practical purposes.
I’m inclined to agree. Unless the framework implements a lot of opinionated behavior that aligns with your product goals, you almost invariably end up fighting it. And on a long enough time line, that tends to happen anyway.
But that’s not why we adopt frameworks. We do it so that engineers are fungible commodities. It makes it easier to find, hire and onboard additional resources. Also requires fewer resources since you don’t need folks on your team dedicated to maintaining your house-built framework.
So, while I agree that building something in house is better for getting exactly what you want from a framework, it isn’t very practical from a business standpoint.
Most code is written to make money. Frameworks make it easy to not only start a project but run it for a long time with fast time to market. I agree that if it was just about writing nice code, libraries are good but if you want to make money writing code, frameworks help do it much faster.
You could argue that you can make money writing without frameworks but at what cost and how many teams can successfully do that ? Framework gives any team (even average ones) the headstart they need to continue to actually do something that makes money.
Too many devs care way too much about having a pretty solution instead of a cost-efficient one. The solutions space usually has a middle ground somewhere (affectionately called 'horrible hack' every once in a while). It's what makes a difference between a software engineer and a programmer.
To paraphrase, anyone can build good software, but it takes an engineer to build good software quickly.
Nothing is stopping one from versioning and packaging their dependencies. Then there is no work to maintain anything and you can address any other changes with your own code if you like.
Libraries can change as well. Frameworks are just that, a bunch of libraries.
I tried this a while back but was put off by the fake "css".
They say "The dialect of CSS used in Textual is greatly simplified over web based CSS and much easier to learn." But I immediately ran into issues trying to use css that I'm familiar with (and it wasn’t even fancy). They should have called it something else and used different syntax.
Rapid application development is probably the wrong description. That’s already used by systems that have UI builders and code integrated, like Delphi etc and early systems like VB.
I went looking for such a thing in this project and only found examples in Python scripts.
I know textualize/rich are HN darling projects, but do we really want full-color mouse driven gui applications full with superfluous animations in our terminals?
I've been using textual a couple of months for live-system-analysis GUI and while the big flashy things with animation/mouse/gigantic whitespace borders are what they show off, you don't have to use any of that; It does take a lot of the complexity out of bigger-than-screen/scrollable windows/mouse interaction/layout details away.
It also has a nice selection of Widgets, including the DataTable, which either works for you, or works as an example of how to build things.
They say they support typing but I was weary as soon as they had a class field which defined actions. Python severely disappoints in its type system when compared to flow or typescript which are turning complete.
It's a very decent Microsoft Paint imitation that runs in your terminal!