50 comments

[ 2.8 ms ] story [ 103 ms ] thread
I love TUIs, mainly because they emphasize keyboard control. This looks much more usable than directly using ncurses!!!
Used this in a project last week, works really well.

I like the calculated positioning system and docs with examples of all the controls!

By the creator of Mono, the first prominent multi platform .NET clone, Xamarin, a forms package (both acquired by Microsoft), and tons of work on GNOME.
Don't forget Midnight Commander, which uses a TUI just like this one.
There are so many Go and Rust TUI apps that I've used that look so much better than this. This reminds me of something straight out of MS-DOS.

I've also yet to find a single .NET application that wasn't sluggish on Linux. Jellyfin, Emby, Jackett, etc all take like 5 seconds to start while Go apps take a few milliseconds.

Probably the JIT, I expect this will improve with ahead of time compiling in the newer dotnet sdks.
FWIW, whenever I've profiled startup of .NET apps the JIT is pretty fast to start up.

The only times I've noticed slow startup on recent .NET versions is with WPF apps, and that seems to be mostly because WPF does so much work on startup.

If I'm not mistaken, use of reflection on startup is a major contributor to slow startup. NativeAOT is both JIT free and reflection free.
NativeAOT has multiple reflection compatibility modes because most code bases rely on it one way or another. Reflection-free mode works in a limited set of scenarios but greatly reduces the binary size since the compiler and linker can reason much better about which parts of the code they can trim away during compilation.
I didn't know about reflection compatibility modes. Thanks!

I hope source generators will eventually replace reflection from most libraries, so that reflection-free mode can become more mainstream.

I am looking right now for terminal ui toolkit. Can you elaborate on these in Go/Rust?
So for Rust... Zellij, gitui, taskwarrior-tui, to name a few.

For Go... cointop is one app I can think of off the top of my head. Bubbletea is an excellent framework:

https://github.com/charmbracelet/bubbletea

Oh I am so sorry. I just realized you mentioned "apps" not terminal frameworks. My apologies for creating effort.

I think the choice of using blue background is a really horrible one :)

Bubble tea seems in a slightly different space .. more like Python rich or .NETs spectre.console.

> Oh I am so sorry. I just realized you mentioned "apps" not terminal frameworks.

LOL... I just went and googled all of these and was like "why am I seeing apps... I want the actual dev libraries so I could build my own apps"

Guess this explains why I was so confused.

>>There are so many Go and Rust TUI apps that I've used that look so much better than this.

Like what?

I write a lot of .NET software that runs on Linux and for console apps, startup is generally comparable to Go - the impact of the JIT on startup times is greatly exaggerated in my experience.

I'm less familiar with startup times for ASP.NET services, maybe that's the difference.

It's from Miguel de Icaza, the creator of Midnight Commander. Of course it looks like MS-DOS. That's the whole point.
I actually kinda like the style but maybe thats just the nostalgia talking!
These are pretty big servers with quite a few features. I haven't seen comparable implementations in go. Are you comparing them to go apps of similar complexity? Also, I'm not sure what you count as startup specifically, but are you sure they're not just doing valid work up front? Servers would normally optimise responses vs startup time.
Thank you! I'm currently using spectre.console[1] for my audio tagger[2] but although it supports "live" refreshing [3], this one seems better to build a real UI and less simple command line app centric. Maybe I'll give it a try for the next TUI project on my list ;)

[1]: https://spectreconsole.net/

[2]: https://github.com/sandreas/tone

[3]: https://spectreconsole.net/live/

A big caveat of Terminal.Gui is that it currently only work full screen. Which is not for everyone. I find myself exactly split between spectre.console and terminal.gui for that reason. There is an issue on topic in Terminal.Gui.
What do you mean exactly by full screen?

I imagine that like most terminal applications you could just use tmux to put it in a pane.

Ah. Yes, that may work but I am more like: i activate the program and then use the next ten lines in the terminal to display my 3 input boxes and not all 20 lines the terminal can use. And when I exit the program I am still in the session above and below.
Ah, is that a Windows thing? I've never done that in Linux, I think, without tmux or something.
Nope it is not. It should be terminal thing in general. On a much more abstract way, Microsoft tries something similar by embedding apps (as in Excel) to be hosted in Teams (aka chat).
Looks like I am installing Windows.

One thing that has kept me away from getting into .NET terminal & desktop apps is the binary size. Even a hello world app is quite big compared to Go, Rust etc.

This confuses me - I have a .net app with useful functionality that I wrote in 2007 and it's a 24kb EXE file with no dependencies other than the runtime. Are you using heavy weight libraries/packages?
> it's a 24kb EXE file with no dependencies other than the runtime

Presumably they're publishing it as a framework independent binary, which includes the runtime

You've got a few options. 1. Every windows 10 these days will have .net framework 4.8, so you can ship just your app. If you're going core, you could try .net 7 and assembly trying + ReadyToRun - I'm not sure how much that's saving but it's supposed to be much better than .net 6 which failed in that case.
Well it depends on how you publish your application. Example:

dotnet publish -c Release -r linux-x64 --self-contained -p:PublishReadyToRun=true -p:PublishSingleFile=true -p:DebugType=None -p:DebubSymbols=false

Will produce a single file which (with only Hell world) is around 62MB. While:

dotnet publish -c Release -r linux-x64 --no-self-contained -p:PublishReadyToRun=true -p:PublishSingleFile=true -p:DebugType=None -p:DebubSymbols=false

(Notice --no-self-contained), will produce a single file which should be around 146KB.

So it all comes down to including the whole runtime or not while publishing. And then there is AOT (Ahead of time) option for the upcoming .Net 7, which will reduce self-contained files significantly.

Ref: https://devblogs.microsoft.com/dotnet/announcing-dotnet-7-pr...

(comment deleted)
I swear console tui libraries has been all the rage lately, seems like since we went beyond ncurses or [newt](https://en.wikipedia.org/wiki/Newt_(programming_library)) there is a new renaissance of tui based software and libraries
I think many devs are really sick of writing 200 hours on 50 files with 20 tools for achieving 2 input boxes. There is a wish for simplicity in UI building no framework can offer (including the terminal ones).
This is us. We had a conversation last week about how much boilerplate bullshit is required to get our biz UI to the users eyeballs.

We are going to investigate developing some domain specific language / fluent interface to accelerate our efforts. Something like this constrained terminal UI experience could be exactly what we need to enable this path sooner than later. My current alternative is to handcraft a bunch of parameterized HTML UI components.

I went down to bare basics in my thoughts: what do we need for an exchange between machines and brains: data bidirectional and commands from human to machine. A surface is basically data + commands. Add some minimalistic styling free horizontal, vertical and z-level stacking plus some stereotypes and you can meaningful interact. The trick now is: rendering in fancy UI can be either provided by a designer (the old dream) or by an AI/algorithm depending on the actual UI (voice, screen, small screen, console, ...) either by smartness or by learning from how the users arrange the output. But never by the program/developer itself.

When you look at the scifi designs .. you will realize: very simple UI (ok they never cover complex shit, but at least they have an idea how to simple do stuff)

My favourite thing is yelling Hey Siri set an alarm for X. I didn't need to touch anything and the thing happened.
The DSL approach is sweet but the key is to get away from styling/beauty in general in developers lifes.
And so you arrive back at XML + XSLT.
This is why a lot of our internal tools are in Dear ImGUI - it's just such a pleasure to make functional UI that still looks acceptable with 5% of the code.
I also think the newer systems oriented programming languages have contributed a lot because a lot of it is in rust or go and it seems people have taken a real interest in trying to rebuild a lot of old terminal oriented tools in general.
Does this gui framework, work with the old windows Command Prompt or do you need to use the new Windows Terminal? I am just wondering for running on servers that dont have the new Terminal yet.
The project is older than the new Windows Terminal.
Windows Terminal is just a "UI" for Command Prompt, or PowerShell, or other Shells.
Looks awesome. Now to reimplement Midnight Commander in C#…
So lovely OMG. I love TUIs. I once discovered a DOS version of Visual Basic - that was so cool. If this is something like WPF but for cross-platform .Net console then I feel so excited I can hardly even think...
Was it Visual Basic or QBasic?
I mean VisualBasic for DOS. It was exactly what one would expect a VisualBasic to be - a visual draw-and-click RAD IDE for pseudographic windowed event-driven TUI apps. It apparently was rather exotic while QuickBasic/QBasic were very well known.
I don't see the need for this. Character based UI's have long since disappeared from mainstream and here de Icaza is spending time and effort creating a mouse-based character UI?
there is also a port of the "original":

https://github.com/magiblot/tvision

A modern port of Turbo Vision 2.0, the classical framework for text-based user interfaces. Now cross-platform and with Unicode support.