[HN Gopher] How to choose colors for your CLI applications (2023)
___________________________________________________________________
How to choose colors for your CLI applications (2023)
Author : kruuuder
Score : 135 points
Date : 2026-01-29 14:49 UTC (8 hours ago)
(HTM) web link (blog.xoria.org)
(TXT) w3m dump (blog.xoria.org)
| j4cobgarby wrote:
| Use only default (white/black), red for bad, green for good. If
| you need more than that, like vim or whatever, then maybe a
| 'fullscreen' TUI is better, with a specified background and
| foreground. For CLI tools, I'm not sure if I prefer more colours.
|
| The CSS to make the terminals look like iTerm was smooth, to the
| point I read them as screenshots.
| busterarm wrote:
| > red for bad, green for good
|
| 8% of men of Northern European descent (and 0.4% of women) are
| red-green colorblind. That'd be a terrible choice. Use blue-
| orange, blue-red, or purple-green.
| makapuf wrote:
| More importantly, dont use color as sole source of
| information. Strikethrough, emoji or ok / bad can also be
| used.
| xenophonf wrote:
| Emojis aren't 7-bit clean. They're hard to type. They don't
| mean things the same way words do. `foo | grep -i error`
| communicates intent better than `foo | grep :-/` or
| whatever goofy hieroglyph someone chose instead of, like, a
| word with clearly defined meaning.
| craftkiller wrote:
| > They're hard to type
|
| I'd like to recommend rofimoji. I have it bound to a
| hotkey, so whenever I want to type an emoji, I just hit
| that hotkey and then a window pops up with my most recent
| emoji already visible at the top. Then I start typing in
| words that describe the emoji that I want like "crying"
| and it filters the list. Finally I select one and it
| pastes it into whatever text box I had selected before I
| hit the hotkey. My only complaint is I wish it worked for
| all unicode codepoints instead of just the emoji.
| makapuf wrote:
| Yes that's why I also mentioned text labels.
| (strikethrough ansi codes aren't also fun to type).
| Besides, where are you needing 7but clean data ? Isn't
| that a narrow use case ?
| Lammy wrote:
| > They're hard to type.
|
| Globe key + E on Mac, Windows key + period on Windows,
| Ctrl + period on GNOME, Super key + period on KDE, yada
| yada.
| skydhash wrote:
| Red/green is semantic in these cases. They're user
| configurable in almost all terminals, so there's no real
| accessibility issue. I tend to associate blue with decorative
| accent, yellow with info/warning text, and cyan and magenta
| for really fancy stuff.
| tczMUFlmoNk wrote:
| Red/green has no inherent semantics. It has the semantics
| that you assign it. If you choose to assign it meaning that
| disenfranchises 8% of men using your system, that's your
| choice, but it is not a good one.
| skydhash wrote:
| Cultural semantics (diff tools, build tools,...:
| green/addition/ok, red/removal/error). And people with
| color blindness can alter the colors to something they
| can differentiate. And in the ansi sequences, they are
| actually numbers.
| mrob wrote:
| The standard terminal palette is only 16 colors. Even if
| you compress them all into the green-to-blue color range,
| it's still possible to distinguish all 16. The user can
| change "red" and "green" to whatever they like in the
| terminal preferences and then every 16-color app will be
| accessible with no additional effort from anybody.
| Etheryte wrote:
| This approach is worse. Use red and green like everyone else
| and the user can choose their terminal color palette to
| differentiate in a way that works for them. Then it works the
| same across all commands. If you're the odd one out, you're
| adding more mental overhead for the user, not less.
| account42 wrote:
| You are ignoring that most people already have a cultural
| understanding of the colors red and green. Changes done for
| accessibility should never making things worse for the
| average user.
| BeetleB wrote:
| Hard disagree on the red/green. Use whatever you think
| appropriate and make it user configurable.
| mrob wrote:
| It's a CLI app, it's already configurable. Every good
| terminal emulator lets you set custom palettes.
| kps wrote:
| >Every good terminal emulator lets you set custom palettes
|
| Not _differently for each program 's output_.
| mrob wrote:
| Which is a good reason to stick with the de-facto
| standard of red for bad and green for good.
| sceptic123 wrote:
| unless you're colour blind
| mrob wrote:
| If you're color blind, you change the palette in your
| terminal emulator so "red" and "green" become different
| colors you can distinguish. It even works for rarer forms
| of color blindness. This works best when people follow
| the de-facto standard.
| skydhash wrote:
| Red here does not mean #ff0000. it means color 1. in the
| 4 bit colors palette
| BeetleB wrote:
| If for something unrelated to good/bad looks good, I'm
| using red. Ditto for green.
|
| Sure, if it was a status indicator and I used red for
| "good", I can see the point. But over the last few years
| I've had too many people tell me "Don't use red, people
| will think something is wrong" for things not
| semantically tied to good/bad.
|
| People wear red clothes. They buy red cars. They eat red
| food. They date red heads. Red is OK.
| red_admiral wrote:
| Eh, LS_COLORS is sometimes useful once the meanings are in your
| subconscious.
| fassssst wrote:
| Color is cultural. Red is associated with good in China
| altcognito wrote:
| Context here matters, red finds its way into Chinese
| forbidden or warning signs quite often.
| xenophonf wrote:
| I really wish you wouldn't. All the rinky dink colors and
| animations screw with the CLI output when you don't correctly
| detect whether the user's running the app interactively.
|
| Keep it plain text. Regular, old, boring output is good.
| skydhash wrote:
| I dislike when devs only try to detect if it's a tty, then
| enable all their gimmicks without even providing a flag. Not
| everything is xterm-256color.
| kps wrote:
| And not everything that calls itself xterm-256color is
| actually xterm compatible *cough* GNOME *cough*.
| bitwize wrote:
| Xterm is actually a terminal emulator, and has to pass a
| suite of conformance tests that actually check its
| emulation of DEC VT series terminals.
|
| Most of its successors are more like "shitty xterm
| emulators" whose conformance tests are "do my favorite
| mOdErN CLI apps work".
| davidw wrote:
| Yeah. "The only winning move is not to play".
| bitwize wrote:
| I agree. So many TUIs from webshit devs don't even bother to
| call isatty, let alone check terminfo to see if ANSI escape
| codes are even valid for this terminal.
|
| But modern open source subscribes to Mao's Continuous
| Revolution Theory. Calls for some measure of stability and
| sanity are usually dismissed with some form of the argument
| "awwww, is poor diddums afwaid of a widdle change?" Or in this
| case, "still using vi on your ADM3A, old timer? Our software is
| not for you."
| sroussey wrote:
| This is true for the console in dev tools as well.
|
| Problem there is you can't change css so at the moment the
| systems color preference changes thing will look bad.
|
| Important considerations for custom formatters.
| sroussey wrote:
| Here is a screenshot for my personal example:
|
| https://github.com/workglow-dev/workglow/blob/main/docs/deve...
|
| Play with it here using dev tools (you can ignore the website
| itself): https://workglow-web.netlify.app/
|
| Docs including util for checking dark mode:
| https://github.com/workglow-dev/workglow/tree/main/packages/...
| seanwilson wrote:
| If the goal of the post is to pick terminal colors that contrast
| on both white/light and black/dark backgrounds, it means you're
| stuck with midtone colors (between light and dark). This is
| really limiting for color choice (there's no such thing as "dark
| yellow" for example), and lowers the maximum contrast you can
| have for text because you get the best contrast when one color is
| dark and the other is light.
|
| Ideally, instead of the CLI app switching to "bright green", it
| would pick a "bright contrasting green". So if the terminal
| background was dark, it would pick bright green, and for light
| background it would pick a darker green. There isn't CLI app
| implementations for this? This is similar to how you'd implement
| dark mode in a web app.
| alt187 wrote:
| That's called `\e[0;92m`, aka the ANSI terminal espace sequence
| for bright green. You have 15 others, that will be displayed
| however the terminal's user wants. They're already available in
| most terminal color libraries, too.
| account42 wrote:
| > Ideally, instead of the CLI app switching to "bright green",
| it would pick a "bright contrasting green". So if the terminal
| background was dark, it would pick bright green, and for light
| background it would pick a darker green. There isn't CLI app
| implementations for this? This is similar to how you'd
| implement dark mode in a web app.
|
| The responsibility for this lies with the color scheme not the
| terminal program.
| JoshTriplett wrote:
| CLI apps can detect the background color of the terminal, and
| determine contrasting colors accordingly.
| takluyver wrote:
| They can? Is this a recent thing? I remember wanting to
| detect the background colour years ago, and not finding any
| way to do it.
| JoshTriplett wrote:
| It's not recent, and most terminals support it. You send an
| escape sequence to the terminal, and get back a sequence
| that tells you the exact background color.
| takluyver wrote:
| Huh, indeed. I still can't find much information about
| this, but this page is very informative:
| https://jwodder.github.io/kbits/posts/term-fgbg/
| red_admiral wrote:
| There's an ever more basic rule: don't just make your text white
| (ANSI 37m) because you assume the terminal will have a dark
| background. Even white-on-black (37;40m), while usually readable,
| can stand out the wrong way if you assume that everyone is using
| dark mode.
| account42 wrote:
| IMO if your terminal theme does not provide high contrast for
| "white" text on the default or "black" backgrounds, that's for
| you to fix. If you want a light terminal then change the color
| scheme to map "black" to a bright color and "white" to a dark
| color while making sure that other colors have good contrast to
| your "black". Don't just change the default foreground and
| background color and expect every single color using program to
| fix your mess.
| bitwize wrote:
| It's 2026, and app developers are solely responsible for not
| causing eyehurt, even if their users insist on using the Hotdog
| Stand theme.
| keepamovin wrote:
| Can you work this into an AGENTS.md ? Just so happen to be
| working on multiple TUI at the moment: text-based modern web
| browser, VPS rental console, agentic coding wrapper.
|
| Colors, have been a perpetual nightmare.
| alias_neo wrote:
| I recently spent several evenings re-working all of my colours
| across all of my computers and screens; terminals, IDEs, etc.
| Ultimately, despite using the same tools, and always dark mode,
| across all of my machines, the setup for each was different.
|
| I think it's safe to set a standard colour-set so that it's
| immediately usable, but beyond that, a user should be customising
| to their requirements.
|
| Perception differs among people; many of the colours OP listed as
| unreadable, were barely an issue, bright yellow being the only
| one I could unequivocally agree on. Perhaps display type,
| configuration and colour calibration is an important factor, as
| well as individual perception, ambient conditions, brightness
| levels, contrast, and perhaps even more variables have a
| significant effect.
|
| I've also learned, since adding an OLED Monitor to my desk
| alongside the IPS ones, that it's possible to have too much
| contrast; brightly coloured text alongside pixels that are
| literally off can be just as problematic to read at times, as
| low-contrast.
| layer8 wrote:
| As long as CLI programs stick to the 8 or 16 standard colors and
| refrain from setting background colors (inverse mode is fine), as
| well as from explicitly setting white or black as text color,
| everyone can reasonably configure their terminal colors so that
| everything is readable.
|
| When going beyond that, the colors really need to be configurable
| on the application.
| JohnLeitch wrote:
| > refrain from setting background colors
|
| That's the thing though, setting bg color opens up a lot of
| options, and constraining to invert is not sufficient in my
| opinion.
| Joker_vD wrote:
| > constraining to invert is not sufficient in my opinion
|
| Eh. Doing green/red text color with default background, maybe
| inverted works amazing for me. In fact, I'd say that every
| sensible colour scheme for a terminal should have as the
| default foreground/background colours something that is more
| or less contrasting against every other explicitly named
| colour, including black and white (I personally have #212121
| on #EEEEEE).
| layer8 wrote:
| That's fine, but please make the colors configurable then.
|
| For example like Mutt does:
| http://www.mutt.org/doc/manual/#color
| Arch-TK wrote:
| Configurable within the application... at runtime.
|
| I want to be able to switch existing terminals with existing
| applications between themes.
| jammcq wrote:
| I'm a bit color blind and it might be quite common to show errors
| in red but when the background is black, I can't see it at all.
| bradrn wrote:
| Neither can I. Luckily tweaking the colours can make it
| _somewhat_ readable. (Sometimes...)
| s_dev wrote:
| Colourful terminals are so useful. I have mine colour coded
| according to the working directory depending on the project. So I
| can see which terminal is associated with which project even if
| there are twenty terminals open. The scripts are even in my
| servers so when I ssh in to them it changes colour as well.
|
| https://michael.mior.ca/blog/coloured-ssh-terminals/
| thinking_cactus wrote:
| Interesting analysis, but perhaps it warrants a different
| conclusion: it's almost impossible to please everyone in this
| case. The resulting colours seem of some utility, but if you
| intend to make something more interesting you're probably annoy
| some (potentially large) group, in the case of legacy terminal
| coloring.
| hnsmhthrow wrote:
| I used solarized since it came out but I dropped it some years
| back. I don't think I can use it for dark mode. It's too washed
| out and dull compared to light mode which is what I used to use
| it with. I just use whatever VS Code or VIM gives me as a dark
| mode and it's usually better.
| ori_b wrote:
| As long as you respect the NO_COLOR variable, it will work for
| me.
|
| https://no-color.org/
| jph wrote:
| If you want a quick easy way to add some colors to your own shell
| scripts: export STDOUT_COLOR_START='[34m'
| export STDOUT_COLOR_STOP='[0m' export
| STDERR_COLOR_START='[31m' export
| STDERR_COLOR_STOP='[0m'
|
| In your shell script: print_stdout() {
| printf %s%s%s\\n "${STDOUT_COLOR_START:-}" "$*"
| "${STDOUT_COLOR_STOP:-}" } print_stderr() {
| >&2 printf %s%s%s\\n "${STDERR_COLOR_START:-}" "$*"
| "${STDERR_COLOR_STOP:-}" }
|
| Source: https://github.com/sixarm/unix-shell-script-kit
|
| The source also has functions for nocolor, and detecting a dumb
| terminal setup that doesn't use colors, etc.
| direwolf20 wrote:
| What is the purpose of making everything the same color?
| Rygian wrote:
| stdout and stderr get different colors.
| kps wrote:
| 1. That script's color check doesn't check that the output is a
| terminal. Also test tty -s
|
| 2. Don't hardcode escape sequences. Use (e.g.)
| export STDOUT_COLOR_START="`tput setaf 4`".
| wpm wrote:
| If you're writing a zsh script and not worried about
| portability, you can also use the prompt expansion colors with
| "print". print_color () { print -P
| "%F{$1}$2%f" }
|
| And then to use it print_color "green" "This
| is printed in green"
| leephillips wrote:
| Nice. I put this in my .zshrc.
| godelski wrote:
| Here's something also useful that's portable
| declare GRN='\e[1;32m' declare RED='\e[1;31m'
| declare YLW='\e[1;33m' declare CYN='\e[1;36m'
| write_log() { echo -e "[$( date +'%c' )] :
| ${1}\e[0m" | tee -a ${logfile} } write_log
| "${RED}I'm an ERROR"
| godelski wrote:
| That seems needlessly cumbersome, why not
| declare STDOUT_COLOR='\e[34m' declare
| STDERR_COLOR='\e[31m' declare COLOR_STOP='\e[0m'
| print_stdout() { echo -e
| "${STDOUT_COLOR}${*}${COLOR_STOP}" &> /dev/stdout }
| print_stderrr() { echo -e
| "${STDERR_COLOR}${*}${COLOR_STOP}" &> /dev/stderr }
|
| Like why are you exporting? Do you really need those in your
| environment?
|
| And those print statements aren't going to work by default.
| makapuf wrote:
| I really think we should converge to semantic codes. By example
| Background is zero, standard is 7, positive / negative,
| highlight, colored1,2,3 .. with correct defaults, and let the
| user have a common 8 or 16 colors palette in the terminal for all
| textmode apps. Imagine having some kind of unified color themes
| in the terminal.
| tolciho wrote:
| A confused user once stopped by, they had a blank terminal, so I
| showed them how to select all which revealed the helpfully black
| on black text. These days I compile colour support out of st, or
| set *colorMode:false for xterm. "But you can customize the
| colours" is a typical response, to which one might respond that
| one has grown weary of pushing that particular rock, and moreover
| one may be busy with other things at a drag-out monitor in a
| server room at three in the morning that has helpfully dark blue
| text on a black console, or worse if some high-minded expert has
| gone and rubbed the backside of a unicorn everywhere so that they
| may improve the "legibility".
| munificent wrote:
| Tangential, but I really love the design of this blog.
| otabdeveloper4 wrote:
| Step one: *always* assume a dark background.
| nateroling wrote:
| I've bounced off of LazyGit multiple times because I never
| figured out how to make it play nice with a light theme terminal.
|
| I haven't used dark mode anything for years. I set my monitor so
| it's roughly as bright, or slightly brighter than, a piece of
| white paper.
|
| No more flash-bangs when some website doesn't support dark mode.
| assimpleaspossi wrote:
| Black on white has seemed to work for centuries without issue.
| For general reading, throw in bold and italic and you're pretty
| much set. For programming, black on white is still a go to color
| (or lack thereof).
| lifetimerubyist wrote:
| I use the built-in TokyoNight Day theme as my light theme in
| GhosTTY and I think it's almost perfect. Then I use
| TokyoNightMoon for dark. Works great. Hard to use anything else
| now.
|
| If you're CLI application doesn't play nice with it (i haven't
| seen many) I don't use it.
| joshka wrote:
| I made the "Aardvark Blue" a while back[1] to solve some of the
| problems that most color schemes have. The goal of this theme is
| that:
|
| - colors are fairly natural
|
| - background and black are distinct
|
| - grays are naturally ordered avoiding full black
|
| - light and dark colors are distinct from each other
|
| - all colors look good on background, black, dark gray, gray,
| white
|
| We use this for all the screenshots on https://ratatui.rs and
| https://github.com/ratatui/ratatui
|
| It's available from the usual places
| https://iterm2colorschemes.com/,
| https://windowsterminalthemes.dev/?theme=Aardvark%20Blue, built
| in to ghostty, extension for vscode etc.
|
| [1]: https://github.com/mbadolato/iTerm2-Color-Schemes/pull/417
| tasuki wrote:
| Funny thing, those are not "the usual places" I've ever heard
| of, and I care somewhat about color schemes. Each of us lives
| in our own bubble... (my bubble is not iterm2 and not windows)
| anal_reactor wrote:
| The problem with CLI colors is that they operate on the wrong
| abstraction layer. Individual program shouldn't send "this text
| is red" but "this text signals failure" and then terminal
| interprets "failure" as "red". Until this change happens (never)
| colors in CLI will remain a hot mess.
___________________________________________________________________
(page generated 2026-01-29 23:00 UTC)