The checking of the terminal mode on every panic is already gaining more complexity than I like, see PR. This got me to think that setting the terminal to raw mode seems out of scope for basic-cli. I see how it's a useful feature but I don't think it fits our basic scope. What do you think?
I agree that maybe this functionality is going beyond basic. I don't know how we should proceed though. Either we try to make the platform a proper cli platform with all expected functionality, or we (re)move the tty functionality.
I saw there is a tui-platform in the examples. Maybe this can be made into a proper tui-platform with terminal raw mode?
The only downside is that this is the most extensive zig platform in the examples, so changing it to a rust platform would remove that example
The checking of the terminal mode on every panic is already gaining more complexity than I like
Why? The app is just closing on panic. It isn't like that is extra logic running all the time or slowing the app down. It also points out what may be an important pattern for many apps (cleaning up if roc panics).
I think that naturally basic-cli will gain complexity over time. I think the only reason it is called basic- is to let people know the level of support and polish to expect.
setting the terminal to raw mode seems out of scope for basic-cli
That is a solid maybe. I guess it depends on the goal. As pointed out by @Luke Boswell, when using a terminal in raw mode, we generally want a different sort of input. We don't want to read stdin the same way that normal apps would. We also likely want multi-threading.
My gut feeling is that it should mostly depend on the usefulness without adding a ton of features to basic cli (or at least first validating the group of features and then deciding if they are wanted as a whole). In my mind, I think basic-cli should support remaking most terminal apps shipped with linux. Most of them would not need raw mode, but something like top would. That said, can we support something with a ui like top without a ton of complexity and other features? If not, is it worth having the group of features?
Aside, if the main use of raw mode is terminal games and we have no real goals to support something the top, I think that raw mode should just have its own platform specific to terminal games.
Why? The app is just closing on panic. It isn't like that is extra logic running all the time or slowing the app down. It also points out what may be an important pattern for many apps (cleaning up if roc panics).
First we thought we could get away with a boolean, then we moved to the threadsafe AtomicBool but from the rust docs we learned that "This type is only available on platforms that support atomic loads and stores of u8.", so I thought we could use #[cfg(target_has_atomic = "8")] to set up some conditionals. These conditionals can be abstracted away so it would be good make a separate rust file for that, to keep the main lib.rs clean. Then I thought we could use a mutex instead, which has no support caveats, but now deadlock risks start creeping in, and I really want basic-cli to be reliable and as simple as possible. You see how this is going :p
I think all of these concerns are very solvable an shouldn't be a big deal:
Currently, basic-cli has no threading, so we can use just a bool for now and re-evaluate later.
This type is only available on platforms that support atomic loads and stores of u8
I am pretty sure that covers all platforms that basic-cli plans to support. So this should also be fine.
Aside, we could just use an AtomicUsize set to 0 or 1. It is guaranteed to be supported.
Then I thought we could use a mutex instead, which has no support caveats, but now deadlock risks start creeping in.
What deadlock risks? It is a single variable that would be wrapped in a mutex and used in controlled situations with that can't hold onto the mutex for a long time.
Oh, side, thought, do we need the bool at all?
If raw mode is disabled and we try to disable it again, what does it do? If it just becomes a no-op, we probably can just do that without any mutex, atomic, or bool.
I'll check that out.
Another relevant consideration is that we introduced the crossterm crate as a dependency, to be able to switch to raw mode.
I believe that we should not set the bar this low for introducing dependencies (for a use case like this) to our designated hello world platform.
Brendan Hansknecht said:
Oh, side, thought, do we need the bool at all?
If raw mode is disabled and we try to disable it again, what does it do? If it just becomes a no-op, we probably can just do that without any mutex, atomic, or bool.
On unix systems, crossterm's disable_raw_mode is literally a noop in the source, if it is not enabled. The windows version I don't understand at a glance, but I suspect they would make their behavior do the same
Also, enabling and disabling already uses a mutex in crossterm, so it should be thread-save if we just use it without extra stuff in the platform
I guess my thought is we should consider the scope of basic CLI, but I wouldn't personally worry about the complexity in this case.
What is the goal of raw mode? Who wants it and what are the uses? Why should it be in basic CLI and not its own platform?
After this discussion my opinion is as long as it is just an example like every platform at this point, we can leave it. When the time comes when there needs to be a production cli platform the question can come up again
It already seems likely that basic-cli will become a very popular and thus unavoidably a production platform. Users also don't enjoy having functionality they rely on taken away, so if we want to take it out, it's best to do it as early as possible.
One of the main motivations for adding it was to unlock a whole bunch of potential things you can do with Roc today. If people can make small games or apps using the terminal then that might be a cool way to learn the language, particularly the platform/task abstraction.
maybe once we have shared effects across platforms, we can split it into two?
I think this will be an excellent thing for us to test platform independent effects. :+1:
I'll mention in the docs that the raw mode related functions are planned to be moved in the future.
@Anton I updated the PR to remove the AtomicBool and the check in roc_panic
One of the main motivations for adding it was to unlock a whole bunch of potential things you can do with Roc today
I saw today in the docs that it will be removed and was a bit sad. I want to try out different things with roc since I come from web development and have no experience with this stuff.
I basically learned about the existence of raw mode 10 minutes ago :)
Probably, I would not be sad if it wasn't supported, but if I could still add it easily somehow with zig. It seems now that I need to wait couple of weeks until new way making platforms will be released. Since it is pretty confusing right now.
p.s. sorry I still confused by zullip and why it creates new messages and not adds them to a thread
This is an old thread... I read back to get some context.
I don't think we have plans to remove Tty.enable_raw_mode! : {} => {} anytime soon. It's kind of settled into basic-cli and hasn't really been an issue.
Yeah, given that it has generated no problems we can leave it in.
Ruby has marked this topic as resolved.
Last updated: Jun 16 2026 at 16:19 UTC