@mjakl/pi-dark-or-light
Auto-switch pi between light and dark themes using hierarchical detection
Package details
Install @mjakl/pi-dark-or-light from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@mjakl/pi-dark-or-light- Package
@mjakl/pi-dark-or-light- Version
1.0.0- Published
- Mar 7, 2026
- Downloads
- 19/mo · 4/wk
- Author
- mjakl
- License
- MIT
- Types
- extension
- Size
- 17.9 KB
- Dependencies
- 0 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-dark-or-light
pi-dark-or-light is a pi extension that automatically chooses a dark or light theme for pi.
It is meant for people who want pi to follow the appearance of their system or terminal without hard-coding a single theme value in settings.json.
What it does
- Detects whether your environment is currently dark or light
- Applies the matching pi theme when a UI session starts
- Only runs in UI sessions; it does not do anything in headless/non-UI runs
- Re-checks every 5 seconds, so appearance changes can be picked up while pi is running
- Lets you map detected
dark/lightmodes to either pi's built-in themes or your own custom theme names - Re-applies the detected theme even if pi persists a top-level
themesetting internally
In short: this extension decides dark vs light, and you can optionally decide which actual theme name should be used for each mode.
When the extension is active
This extension manages the theme whenever it is loaded in a UI session.
If pi or another workflow writes a top-level theme into settings.json, this extension still keeps applying the detected dark/light result on startup and during polling.
Installation
Option 1: Install from npm (recommended)
pi install npm:@mjakl/pi-dark-or-light
Option 2: Install via git
pi install git:github.com/mjakl/pi-dark-or-light
Option 3: Install from a local checkout
pi install /path/to/pi-dark-or-light
Option 4: Development or one-off testing
pi -e /path/to/pi-dark-or-light/src/index.ts
Package name: @mjakl/pi-dark-or-light
Quick start
- Install the extension.
- Optionally add a
dark-or-lightmapping.
Minimal setup:
{
"dark-or-light": {
"dark": "dark",
"light": "light"
}
}
Example with custom themes:
{
"dark-or-light": {
"dark": "tokyo-night",
"light": "github-light"
}
}
If you do not configure a mapping, the extension uses pi's built-in dark and light themes.
For details on pi themes themselves, including built-in and custom theme setup, see pi's own themes documentation.
Configuration
The extension reads settings from the same places pi normally uses:
- Global:
~/.pi/agent/settings.json - Project:
.pi/settings.json
Project settings override global settings.
For the extension-specific config, use either:
dark-or-light(recommended)darkOrLight(also accepted)
Supported config
{
"dark-or-light": {
"dark": "theme-name-for-dark-mode",
"light": "theme-name-for-light-mode",
"default": "dark"
}
}
All keys are optional.
dark: theme name to use when detection resolves to dark modelight: theme name to use when detection resolves to light modedefault: fallback mode to use when no detector returns an answer; allowed values aredarkandlight
For example, this is valid too:
{
"dark-or-light": {
"dark": "tokyo-night"
}
}
In that case:
- detected
dark->tokyo-night - detected
light-> built-inlight
You can also change the final fallback mode. For example:
{
"dark-or-light": {
"default": "light",
"light": "github-light"
}
}
In that case, if no detector succeeds, the extension chooses light, which then maps to github-light.
Merge behavior
Global and project dark-or-light settings are merged field-by-field, with project settings overriding global ones.
Use the same key spelling in both files if you rely on merging. In other words, do not mix dark-or-light in one file with darkOrLight in the other.
Example:
Global settings:
{
"dark-or-light": {
"dark": "tokyo-night",
"light": "github-light"
}
}
Project settings:
{
"dark-or-light": {
"dark": "gruvbox-dark"
}
}
Result for that project:
dark->gruvbox-darklight->github-light
If a mapped theme cannot be loaded
If you map dark or light to a custom theme name and pi cannot apply it, the extension falls back to the built-in dark or light theme for that detected mode.
Detection order and heuristics
The extension uses a fixed detector chain. The first detector that returns a clear answer wins.
Overall order:
- macOS native appearance
- Windows native appearance
- tmux client theme
DARK_MODEenvironment variableCOLORFGBGheuristic- Fallback to configured
defaultmode (default:dark)
Detectors that do not apply on the current platform are skipped.
How it decides on each operating system
macOS
On macOS, the extension first asks the OS directly:
- Runs
osascript - Queries System Events for the current dark mode setting
true->darkfalse->light
If that does not return a usable answer, it falls through to the shared terminal-based detectors below.
macOS order:
- Native macOS appearance via
osascript - tmux
#{client_theme} DARK_MODECOLORFGBG- Fallback to configured
defaultmode (default:dark)
Windows
On Windows, the extension first checks the user theme setting in the registry:
- Reads
HKCU:\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize - Uses
AppsUseLightTheme 0->dark1->light
If that fails, it falls through to the shared terminal-based detectors below.
Windows order:
- Native Windows appearance via
AppsUseLightTheme - tmux
#{client_theme} DARK_MODECOLORFGBG- Fallback to configured
defaultmode (default:dark)
Linux and other Unix-like systems
There is currently no desktop-environment-specific Linux detector in this extension.
That is intentional: Linux appearance settings vary a lot across GNOME, KDE, sway, Hyprland, remote shells, containers, and headless sessions. Instead of guessing, the extension uses terminal-oriented signals that are more portable.
Linux / other Unix order:
- tmux
#{client_theme} DARK_MODECOLORFGBG- Fallback to configured
defaultmode (default:dark)
Shared detectors
tmux
If pi is running inside tmux, the extension tries:
tmux display-message -p #{client_theme}
Accepted values are normalized case-insensitively:
darklight1/true->dark0/false->light
This detector is only attempted when the environment suggests pi is running in tmux (TMUX is set or TERM_PROGRAM=tmux).
DARK_MODE
If the DARK_MODE environment variable is set, the extension accepts these values:
dark,1,true->darklight,0,false->light
This is useful when you want to force the result from a shell profile, wrapper script, launcher, or platform-specific automation.
COLORFGBG
If no stronger detector succeeds, the extension uses COLORFGBG, similar to pi's built-in heuristic.
It parses the second ;-separated field of COLORFGBG. In the common two-part form, that field is the background color index.
- parses the second
;-separated field - if that color index is
< 8, it choosesdark - otherwise it chooses
light
Examples:
COLORFGBG=15;0-> second field0->darkCOLORFGBG=0;15-> second field15->light
If your terminal emits a more unusual multi-part COLORFGBG value, this detector may not apply and the extension will continue down the chain.
Final fallback
If none of the detectors above produce an answer, the extension falls back to the configured dark-or-light.default mode.
Default if unset:
dark
Allowed values for dark-or-light.default:
darklight
Behavior summary
- Applies a theme on UI session start
- Polls every 5 seconds for changes
- Ignores detector failures and keeps going down the chain
- Uses project settings over global settings
- Merges
dark-or-lightconfig between global and project settings when both use the same config key spelling
Recommended setup
If you want pi to follow your environment automatically:
- Configure
dark-or-lightif you want custom theme names - Let the extension choose the current mode from OS/terminal signals
If you want a fixed theme instead, disable or remove this extension.
Acknowledgements
This extension was influenced by pi's own macOS theme example:
License
MIT