Standard for Dark/Light Preference in Terminals
CLI applications that make use of truecolors have to pick what background they optimize for. Instead of making assumptions, some tools have started to detect dark/light mode by querying the terminal.
There is currently no way to override/disable auto-detection for all these tools in a single, standardized way.
This document aims to establish the CLITHEME
environment variable as a way
for users to communicate their dark/light preference to CLI applications.
It is not meant to replace automatic detection.
Syntax
CLITHEME = ( "dark" | "light" | "auto" ) [ ":" modifier ]*
Zero or more modifiers preceded by a ":" may follow one of the keywords. Unrecognized modifiers must be ignored.
Interpretation
The value is interpreted as follows:
- "dark":
Use colors optimized for a dark background. - "light":
Use colors optimized for a light background. - "auto": (default) Attempt to auto-detect the theme. Applications should not try to detect the theme if stdout is redirected.
Unrecognized values are treated the same as "auto".
How To Implement
import os, sys
def cli_theme():
theme_with_mod = os.environ.get('CLITHEME') or 'auto'
theme = theme_with_mod.split(':')[0]
if theme == 'dark' or theme == 'light':
return theme
elif sys.stdout.isatty():
return detect_cli_theme()
else:
return 'dark'
Adoption
Support | Tool / Library | Notes |
---|---|---|
unknown | systemd run0 | todo: create issue |
unknown | bat | todo: create issue |
unknown | delta | todo: create issue |
unknown | glow | todo: create issue |
unknown | terminal-colorsaurus | todo: create issue |
unknown | delta | todo: create issue |
unknown | Neovim | todo: create issue |
unknown | Helix | todo: create issue |
unknown | difftastic | todo: create issue |
Appendix
Dark/Light Mode Detection
There are currently two methods for determining whether the terminal uses a dark or light theme:
- Query for the terminal's background color using
OSC 11; ? ST
and classify the returned color. This is widely supported. reference - Query the theme mode directly using
CSI ? 996 n
. This is only supported by a handful of terminals. reference
Why not COLORFGBG
?
The COLORFGBG
environment variable was originally introduced by urxvt
and is not widely implemented (Konsole and iTerm2 set it).
It takes the form fg;bg
(e.g. 15;0
for dark and 0;15
for light).
As opposed to CLITHEME
, it is an environment variable set by the terminal. However,
since environment variables are not updated, it may reflect an out-of-date value when the
terminal changes its theme whereas OSC 11
and friends reflect up-to-date values.
It would thus be a bad idea to give COLORFGBG
higher priority over escape sequence based detection.