npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mjakl/pi-dark-or-light

v2.0.0

Published

Auto-switch pi between light and dark themes using hierarchical detection

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 / light modes 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 theme setting 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

  1. Install the extension.
  2. Optionally add a dark-or-light mapping.

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 mode
  • light: theme name to use when detection resolves to light mode
  • default: fallback mode to use when no detector returns an answer; allowed values are dark and light

For example, this is valid too:

{
  "dark-or-light": {
    "dark": "tokyo-night"
  }
}

In that case:

  • detected dark -> tokyo-night
  • detected light -> built-in light

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-dark
  • light -> 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:

  1. macOS native appearance
  2. Windows native appearance
  3. tmux client theme
  4. DARK_MODE environment variable
  5. COLORFGBG heuristic
  6. Fallback to configured default mode (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 -> dark
  • false -> light

If that does not return a usable answer, it falls through to the shared terminal-based detectors below.

macOS order:

  1. Native macOS appearance via osascript
  2. tmux #{client_theme}
  3. DARK_MODE
  4. COLORFGBG
  5. Fallback to configured default mode (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 -> dark
  • 1 -> light

If that fails, it falls through to the shared terminal-based detectors below.

Windows order:

  1. Native Windows appearance via AppsUseLightTheme
  2. tmux #{client_theme}
  3. DARK_MODE
  4. COLORFGBG
  5. Fallback to configured default mode (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:

  1. tmux #{client_theme}
  2. DARK_MODE
  3. COLORFGBG
  4. Fallback to configured default mode (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:

  • dark
  • light
  • 1 / true -> dark
  • 0 / 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 -> dark
  • light, 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 chooses dark
  • otherwise it chooses light

Examples:

  • COLORFGBG=15;0 -> second field 0 -> dark
  • COLORFGBG=0;15 -> second field 15 -> 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:

  • dark
  • light

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-light config between global and project settings when both use the same config key spelling

Recommended setup

If you want pi to follow your environment automatically:

  1. Configure dark-or-light if you want custom theme names
  2. 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