Skip to content

[Discussion] System.Console re-design #52374

Open

Description

@adamsitnik

The initial design of System.Console was mainly driven by Windows OS capabilities and available APIs.

When .NET became cross platform, a number of issues arose (click on the details button below to see the full list) as there was no good way of mapping some Windows-specific concepts to Unix. A good example are all Console.Window* APIs: on Unix the Window is owned by the Terminal app, the .NET Console App has no control over it.

The current design makes no distinction between Console and Terminal, which is also a source of plenty of issues (mostly for apps that have redirected output).

Moreover, System.Console is a static class and there is no common abstraction that would allow not only for testing but also for integrating projects like spectre.console and System.CommandLine.Rendering.

By creating this issue I would like to start a public and transparent discussion about what is wrong with the current design of System.Console and how we could fix that. Based on the results of this discussion, I would like to create a proposal for .NET 7.

cc @jonsequitur @KathleenDollard @patriksvensson @colombod @Keboo @HowardvanRooijen @daxian-dbw

Details

Activity

  1. added this to the Future milestone on May 6, 2021
  2. self-assigned this
    on May 6, 2021
  3. ghost added
    untriagedNew issue has not been triaged by the area owner
    on May 6, 2021
  4. adamsitnik commented on May 6, 2021

    @adamsitnik
    MemberAuthor

    @mdh1418 @MaximLipnin is there any chance that you could share your experience from #41184 #50931 ?

  5. mdh1418 commented on May 6, 2021

    @mdh1418
    Member

    @adamsitnik The work in #41184 and #50931 was primarily done to leverage the platform compatibility analyzer and warn users when a particular API was unsupported on the specific platforms. I believe we had taken note of which APIs failed with PlatformNotSupportedException when running library tests on Browser-wasm Android and also iOS +tvOS (which also had PlatformNotSupportedException for System.Console APIs, and we proceeded to mark those APIs with the Unsupported attribute

  6. phillip-haydon commented on May 7, 2021

    @phillip-haydon

    Microsoft needs to give @patriksvensson a ton of money and replace with spectre.

  7. HowardvanRooijen commented on May 7, 2021

    @HowardvanRooijen

    @phillip-haydon If you notice, Patrik is CC'd on the first message in the thread, because we've been having fortnightly calls for many months on the subject! The point of this thread is to mobilise "an army of the willing" who want to see these improvements invested in, and delivered! My original request was "please can we interop between System.CommandLine and Spectre?" 😁

  8. phillip-haydon commented on May 7, 2021

    @phillip-haydon

    I saw, I'm just totally blown away at spectre, been following it on twitter, we need to give Patrik more recognition that he's built something amazing :D (and the contributors to the project too)

  9. removed
    untriagedNew issue has not been triaged by the area owner
    on May 7, 2021
  10. HowardvanRooijen commented on May 7, 2021

    @HowardvanRooijen

    100% I've said that Spectre delivers the "high level productivity API", that enables me to build impressive things quickly. It's like having the WebControls / WinForm Controls / WPF Components for the CLI, but there are also the lower-level APIs that are needed to deliver that experience consistently across all the platforms that .NET Supports. Hence my tagline of:

    Spectre.Console + System.CommandLine = ❤

  11. maloo commented on May 7, 2021

    @maloo

    Please make sure it works great with https://github.com/migueldeicaza/gui.cs

  12. adamsitnik commented on May 7, 2021

    @adamsitnik
    MemberAuthor

    @migueldeicaza would you like to provide some feedback based on your experience with building https://github.com/migueldeicaza/gui.cs?

  13. 23 remaining items

  14. deeprobin commented on Apr 14, 2022

    @deeprobin
    Contributor

    Hi, just wanted to also say that Console.Clear doesn't do what I'd expect on macOS. It should send \u001b[3J\u001b[0;0H (you can test this does what you want using by running printf '\u001b[3J\u001b[0;0H' in the terminal) - this clears the screen and the scroll-buffer and then puts the cursor at the top. Currently it sends something similar to \u001b[2J\u001b[0;0H (not exactly sure exactly what it sends) - this only clears the screen and puts the cursor at the top, it can also scroll down sometimes. I think there is a place for both types of clearing though, but currently we have only the less useful to me. Note: on Windows we only have the full console clearing currently, but I think the other is possible too using special escape sequences (possibly the same ones).

    @hamarb123 I think that bug does relate to the current API. Can you create a new Issue for this?

    Another thing that would be really useful (but I don't know how to do / if it's possible) is have control over the scroll-bar in terminal using an api, because if you go down a line past the end of what's show, the position is still the same according to the api, so having control over both would be great on macOS for restoring positions properly. Unsure if this can be legitimately detected & controlled though.

    I am not sure if this is possible. I guess this is something that belongs to the conhost on windows.

    But there are ANSI control sequences for scrolling 1 (but these are not supported in ANSI.SYS = no DOS-support):

    Description Sequence
    Enable scrolling for entire display <ESC>[r
    Enable scrolling from row {start} to row {end}. <ESC>[{start};{end}r
    Scroll display down one line. <ESC>D
    Scroll display up one line. <ESC>M

    Footnotes

    1. https://www.cse.psu.edu/~kxc104/class/cmpen472/11f/hw/hw7/vt100ansi.htm ↩

  15. zadjii-msft commented on Apr 14, 2022

    @zadjii-msft

    FWIW, no, controlling the scrollbar is not something that's broadly possible with VT/escape sequences. The "scroll up/down" sequences are used for shifting the contents within the active buffer (the "viewport" at the bottom of the scrollback), and account for things like scroll margins, but they don't move the viewport into scrollback.

    Not all terminals have support for scrollback. There have been a few attempts across the ecosystem to try and roll one-off sequences for controlling the position of the viewport, but those aren't widely implemented (to the best of my knowledge).

  16. hamarb123 commented on Apr 14, 2022

    @hamarb123
    Contributor

    Thanks, I tried some of those sequences and none of them scrolled back into the scroll-back on macOS.
    I will make an issue for the macOS clear function as well - thanks.

  17. webczat commented on Apr 14, 2022

    @webczat
    Contributor

    Well what I noticed was mostly things like Read/ReadKey. windows is the os where you can just ReadKey where on unixes it requires switching back and forth between terminal canonical mode, or what is done here, just staying in non canonical mode, so a dotnet console app, even a simple one reading lines, doesn't kinda feel native. Even though the fact itself that you can just ReadKey without doing os specific things is also useful.
    I am wondering, if a new api in any shape appears, will Console still be shown by default for simple things like WriteLine?

  18. hamarb123 commented on Apr 14, 2022

    @hamarb123
    Contributor

    doesn't kinda feel native

    That's another good point @webczat, something like ReadLine doesn't even let you press left and right to move the cursor - I've not seen any other console utility that does this on macOS (except things like vi where it's intentional in certain contexts) - also this doesn't mean they don't exist, I just haven't experienced them.

  19. webczat commented on Apr 14, 2022

    @webczat
    Contributor

    doesn't kinda feel native

    That's another good point @webczat, something like ReadLine doesn't even let you press left and right to move the cursor - I've not seen any other console utility that does this on macOS (except things like vi where it's intentional in certain contexts) - also this doesn't mean they don't exist, I just haven't experienced them.

    Well generally it's exactly the canonical vs non canonical mode. in canonical mode (default) dotnet is not supposed to handle things character by character, just ReadLine should read from terminal until newline, as only full lines are sent to it. In case of non canonical each character is sent and everything including ^u and ^k keystrokes and other such things, backspace etc needs to be directly handled by the program.
    I am on linux BTW.

  20. hamarb123 commented on Apr 16, 2022

    @hamarb123
    Contributor

    @hamarb123 I think that bug does relate to the current API. Can you create a new Issue for this?

    #28355 - seems like I've commented here before also

  21. BDisp commented on Jan 14, 2023

    @BDisp
  22. adamsitnik commented on Jan 16, 2023

    @adamsitnik
    MemberAuthor

    @BDisp please create a new issue, this thread is dedicated to Console re-design

  23. xoofx commented on Jan 4, 2026

    @xoofx
    Member

    Hey, happy new year! ☺️

    I've been following this issue because I ran into the same "gap" in System.Console: it's great for simple CLI I/O, but once you want to build a real TUI (or even a robust CI-friendly CLI), you quickly end up re-implementing terminal concepts that aren't really modeled in the BCL API surface.

    That's why I wrote two libraries:

    • XenoAtom.Ansi: a focused ANSI/VT layer (tokens, parsing/decoding, style model). It provides building blocks like an ANSI tokenizer/decoder and a style/color model that understands terminal concepts such as "default" colors, OSC sequences, etc.
      Repo: https://github.com/XenoAtom/XenoAtom.Ansi

    • XenoAtom.Terminal: a modern, Console-like API that keeps the ergonomics of System.Console, but adds terminal-native features needed by TUIs/CLIs: a unified async input event stream (keys/mouse/resize/paste), scoped state restoration (raw/cbreak, alternate screen, cursor visibility…), markup/styling on top of ANSI, clipboard integration, automatic CI color term aware detection, and testable backends (virtual + in-memory).
      Repo: https://github.com/XenoAtom/XenoAtom.Terminal

    In practice, the biggest missing pieces in System.Console for this space are:

    • A unified event model for input (not just ReadKey/ReadLine), including resize/mouse/paste
    • A capability model (what does this host support?) and safe degradation
    • A first-class ANSI/VT model (styles/colors/defaults, parsing/decoding)
    • A reliable scope model to restore terminal state when exceptions/cancellation happen
    • Testability without depending on a real terminal

    I'm not suggesting the runtime should adopt these libraries, but they might be useful data points for API design discussions here: they show what terminal apps end up needing today, what developers expect ergonomically (Console-like but richer), and where portability issues show up (Windows vs Unix vs CI vs redirected output).

    I plan to write a higher-level TUI on top of XenoAtom.Terminal if folks want to follow more this initiative. ✨

    Hope it helps!

  24. patriksvensson commented on Jan 4, 2026

    @patriksvensson
    Contributor

    @xoofx You should read the source code to Spectre.Console, because it does indeed support:

    • A capability model (what does this host support?) and safe degradation
    • Testability without depending on a real terminal

    About the other points. I would have wished that you brought this up with us so we could have addressed that feedback.

  25. xoofx commented on Jan 4, 2026

    @xoofx
    Member

    @xoofx You should read the source code to Spectre.Console, because it does indeed support:
    About the other points. I would have wished that you brought this up with us so we could have addressed that feedback.

    Hey @patriksvensson - thanks for the reply. You're right: I should have explicitly mentioned Spectre.Console in my post, and clarified why I ended up building XenoAtom.Ansi/XenoAtom.Terminal instead of trying to push these ideas into Spectre.

    I've used Spectre.Console in a few projects and genuinely liked it. The reason I didn't bring this up earlier isn't because I wanted to "compete" or take over, it's more that the direction I wanted to explore would likely have required changes that are pretty invasive for an established, successful project:

    • splitting out a lower-level ANSI/VT + markup layer as a standalone library,
    • keeping a very Console-like surface area (plus low-level backends),
    • pushing widget/screen-buffer concerns into a higher-level library,
    • and supporting the kind of environment I'm targeting with the broader XenoAtom umbrella project: bringing .NET closer to a native OS / custom runtime environment on top of a raw Linux kernel where I want very tight control of the terminal stack and minimal dependencies.

    That would have meant significant design discussions and potentially breaking changes, and I didn't want to burn Spectre's team time (or mine) on something you might not want to take Spectre.Console toward.

    I see XenoAtom.Terminal with distinct goals rather than a replacement for Spectre.Console. Spectre is rightly popular and covers a broader set of UI scenarios; mine will likely stay niche because of my scenarios.

  26. patriksvensson commented on Jan 4, 2026

    @patriksvensson
    Contributor

    @xoofx We’ve actually been working on a similar push as well:

    https://github.com/spectreconsole/terminal
    (our first attempt at a terminal library inspired by Cathode; it’s now in read-only mode)

    https://github.com/spectreconsole/spectre.tui
    (a low-level library for building fast TUI applications)

    We also plan to do much of what you’ve done with your Ansi library, as well as create a unified abstraction layer for the terminal with terminfo integration (and shared primitives).

    That’s why I mentioned that I would have liked you to bring this up with us earlier (since you mentioned Spectre.Console in this issue). I’m not opposed to you creating a library or anything like that, but I think there could be a lot of synergy between our respective efforts.

  27. xoofx commented on Jan 4, 2026

    @xoofx
    Member

    https://github.com/spectreconsole/terminal
    (our first attempt at a terminal library inspired by Cathode; it’s now in read-only mode)

    Yep, I actually tested Cathode too (and opened an issue there a while back), I liked many things there as well (but also many things were not aligned with what I was looking for).

    https://github.com/spectreconsole/spectre.tui
    (a low-level library for building fast TUI applications)

    Spectre.tui is a great initiative! I've worked on UI frameworks before (not terminal-based, D3D12/Vulkan-based), and part of the reason I started XenoAtom.Terminal is that I want to apply some of those lessons to a terminal stack and explore a direction that's likely a bit different from what existing frameworks do.

    That’s why I mentioned that I would have liked you to bring this up with us earlier (since you mentioned Spectre.Console in this issue). I’m not opposed to you creating a library or anything like that, but I think there could be a lot of synergy between our respective efforts.

    On the synergy point: I completely agree, and I'd genuinely like that. One reason I usually don't try to bring these ideas upstream earlier is practical: spare time is so scarce, and for hobby work I tend to bias toward "ship code" over "align on process". For example, I developed XenoAtom.Ansi and XenoAtom.Terminal during my single week of holidays over Christmas; there's no way I could have achieved that pace inside an existing, well-established project where changes typically require more discussion, consensus-building, conventions, and trade-offs. Starting fresh let me get something up and running quickly that I can now iterate on.

    This discussion I think is a good place to share our initiatives and ideas, as I just did. So we are actually doing a bit of that synergy already! ☺️

  28. patriksvensson commented on Jan 4, 2026

    @patriksvensson
    Contributor

    @xoofx Awesome! Let's move this discussion to Mastodon or similar before the whole issue gets locked 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions