tmux-dracula-cpu-temp

star 3

Show CPU temperature in the tmux status bar via the Dracula theme, with dynamic color based on the value (cold/normal/warm/hot), in an update-safe way. macOS (Apple Silicon) version using smctemp. Use when working with tmux, dracula/tmux, or the user mentions adding a CPU temp segment to the tmux status line on a Mac.

kfet By kfet schedule Updated 6/8/2026

name: tmux-dracula-cpu-temp description: "Show CPU temperature in the tmux status bar via the Dracula theme, with dynamic color based on the value (cold/normal/warm/hot), in an update-safe way. macOS (Apple Silicon) version using smctemp. Use when working with tmux, dracula/tmux, or the user mentions adding a CPU temp segment to the tmux status line on a Mac."

Show Mac CPU temp in the tmux status bar (Dracula, colored, update-safe)

The dracula/tmux theme ships widgets for cpu-usage and ram-usage but not CPU temperature. Patching dracula.sh works but TPM updates (prefix + U) will clobber the edit.

The update-safe pattern: keep dracula stock and append an extra segment to status-right in your own .tmux.conf, after the run '~/.tmux/plugins/tpm/tpm' line. run-shell is synchronous, so by the time tpm returns, dracula has already populated status-right and a trailing set -ag status-right "..." sticks.

The script emits its own #[fg=...,bg=...] directive so the background color changes with the temperature.

1. Install smctemp

On Apple Silicon, osx-cpu-temp and istats don't work. Use smctemp — a lightweight CLI that reads CPU temperature directly from the SMC:

brew tap narugit/tap
brew install narugit/tap/smctemp

smctemp -c prints just the CPU temp as a number (e.g. 52.3).

Why smctemp instead of macmon?

We originally used macmon, but it polls Apple's IOReport framework at a 200ms interval (macmon pipe -s 1 -i 200), which causes ~35% CPU usage — far too heavy for a status-bar widget that refreshes every 5 seconds.

smctemp -c does a single direct SMC register read and exits immediately, with negligible CPU overhead.

2. Wrapper script

~/.tmux/scripts/cpu_temp.sh:

#!/usr/bin/env bash
# Print colored CPU temp segment for tmux status bar (macOS, Apple Silicon).
# Uses smctemp (lightweight SMC reader) instead of macmon.
set -eu

NA='#[fg=#282a36,bg=#6272a4] |n/a'

if ! command -v smctemp >/dev/null 2>&1; then
  printf '%s' "$NA"; exit 0
fi

raw=$(smctemp -c 2>/dev/null)

if [ -z "${raw:-}" ]; then
  printf '%s' "$NA"; exit 0
fi

t=$(printf '%.0f' "$raw")

# Mac CPUs run hotter than SBCs — bands shifted up.
if   [ "$t" -lt 60 ]; then bg='#8be9fd'; ico='🥶'   # cyan   cold
elif [ "$t" -lt 80 ]; then bg='#50fa7b'; ico='😎'   # green  normal
elif [ "$t" -lt 95 ]; then bg='#ffb86c'; ico='🥵'   # orange warm
else                       bg='#ff5555'; ico='🔥'   # red    hot
fi

printf '#[fg=#282a36,bg=%s] |%s%s°C' "$bg" "$ico" "$t"
chmod +x ~/.tmux/scripts/cpu_temp.sh

3. Wire it into ~/.tmux.conf

At the very bottom, after the tpm run line:

# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
run '~/.tmux/plugins/tpm/tpm'

# Append CPU temp segment to status-right (after dracula has set it).
# Script emits its own color based on temp value. Survives TPM updates.
set -ag status-right "#(~/.tmux/scripts/cpu_temp.sh)"

Reload:

tmux source-file ~/.tmux.conf

The dracula refresh rate (@dracula-refresh-rate, default 5s) drives how often the temp updates.

Why not patch dracula.sh?

Editing ~/.tmux/plugins/tmux/scripts/dracula.sh to add a cpu-temp case works, but TPM's update step runs git pull in the plugin checkout, so local edits create merge conflicts or get lost. Keeping the segment in your own .tmux.conf plus a script under ~/.tmux/scripts/ puts the customisation entirely in files TPM never touches.

Tip: how tmux interprets #[...] from #(...) output

tmux re-evaluates the stdout of #(command) as a format string by default, so #[fg=...,bg=...] directives emitted by the script are honoured. That's what lets the script set its own background color dynamically.

Gotcha: emoji width on narrow terminals (phone SSH)

This one bites hard. On a ~40-column phone SSH session the status line starts wrapping its last 1-2 characters onto a second row, and every 5-second redraw adds another wrapped row until the screen is a stack of half-drawn status bars.

Root cause: tmux and your terminal disagree on how wide an emoji is. tmux measures the status with its own Unicode width table; some emoji it counts as 1 cell while your terminal renders them as 2. tmux thinks the line fits, doesn't truncate, and the terminal then paints it 1 cell too wide -- and because the status row sits at the bottom with autowrap on, it wraps and scroll-accumulates on every refresh.

It is not all emoji -- only the ones with Unicode Emoji_Presentation=No (legacy "text-presentation" pictographs): 🌡 ☀ ❄ ♨ ✈ ☁ ❤ ✏. tmux follows the spec and counts these 1 cell; terminals render them as 2. Emoji with Emoji_Presentation=Yes (🔥 🥵 🥶 😎 💻 🧊 …) are counted 2 by tmux, matching the terminal -- those are safe.

The thermometer 🌡 (U+1F321) is one of the bad ones, which is why an earlier version of this skill overflowed. The fix: use an Emoji_Presentation=Yes glyph instead. The script above picks a width-2 face per temperature band (🥶/😎/🥵/🔥), so tmux and the terminal always agree and the status never overflows.

Things that do NOT work

  • Variation Selector-16 (U+FE0F): appending to force emoji presentation does not change tmux's width count (verified on tmux 3.6b -- 🌡️ still measures width 1).
  • Trimming spaces: shaving a space compensates for one bad emoji but is fragile -- add another text-presentation emoji and it breaks again. Fix the glyph, not the spacing.

Probe any glyph's tmux width

Stash the string in a user option and pad it with #{p<N>:...}, which uses tmux's own width math (a bare literal after p: is treated as a variable name, so the option indirection is required):

tmux set -g @m '🌡'
tmux display -p '[#{p8:#{@m}}]'   # width = 8 - (trailing spaces)
tmux set -gu @m

Width 1 = will overflow on a 2-cell-rendering terminal; width 2 = safe.

The general cure (terminal side)

The disagreement is really the terminal violating Unicode's default-presentation rule. Many terminals (Blink, Termius, WezTerm, kitty) expose a Unicode-width / "ambiguous = narrow" setting. Making the terminal spec-compliant renders text-presentation emoji as 1 cell too -- then tmux and terminal agree for every emoji and you can use any glyph, thermometer included.

Related

See linux-tmux-dracula-cpu-temp for the Linux SBC variant (Raspberry Pi, Orange Pi) which reads /sys/class/thermal/thermal_zone0/temp instead of using macmon.

Install via CLI
npx skills add https://github.com/kfet/til --skill tmux-dracula-cpu-temp
Repository Details
star Stars 3
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator