Show Spacepal's Space names in SketchyBar
SketchyBar only knows Spaces by number. Spacepal writes the name, note, color, apps and desktop number of every Space to a JSON file whenever something changes, so a small SketchyBar plugin can show "Client B" instead of "4", and a click can switch through Spacepal. This page gives a working item for the current Space's name and one for all Spaces.
Where the data is
Spacepal rewrites state.json on every change:
- Direct version:
~/Library/Application Support/Spacepal/state.json - Mac App Store version:
~/Library/Containers/com.halberd.spacepal/Data/Library/Application Support/Spacepal/state.json
{
"current": "Code",
"spaces": [
{ "id": "…", "name": "Code", "number": 1, "display": "…",
"isActive": true, "isFullscreen": false, "hasCustomName": true,
"symbol": "chevron.left.forwardslash.chevron.right",
"color": "#9B6BF4", "note": "Editor and terminal",
"apps": ["Visual Studio Code", "Terminal"] }
],
"updatedAt": "2026-10-27T09:12:00Z",
"version": 1
}
current is the active Space on the display with the menu bar. color and note appear only when set, and full screen Spaces have no number. With several displays, each display has its own active Space, so more than one entry can have "isActive": true.
If you prefer HTTP, turn on the Local API in Settings, General; curl -s http://127.0.0.1:57301/spaces returns the same JSON. It is off by default.
Item 1: the current Space's name
In sketchybarrc:
sketchybar --add item spacepal left \
--set spacepal script="$PLUGIN_DIR/spacepal.sh" \
click_script="open -g spacepal://overview" \
update_freq=5 \
--subscribe spacepal space_change
And plugins/spacepal.sh (make it executable with chmod +x):
#!/bin/zsh
STATE="$HOME/Library/Application Support/Spacepal/state.json"
# space_change can fire just before Spacepal rewrites the file.
[ "$SENDER" = "space_change" ] && sleep 0.3
LABEL=$(jq -r '.current' "$STATE")
sketchybar --set "$NAME" label="$LABEL"
$NAME and $SENDER are set by SketchyBar. The update_freq poll catches renames and anything the space_change event misses. Clicking the item opens Spacepal's overview.
Item 2: every Space, current one marked
LABEL=$(jq -r '[.spaces[] | select(.isFullscreen | not)
| if .isActive then "[\(.name)]" else .name end] | join(" ")' "$STATE")
sketchybar --set "$NAME" label="$LABEL"
For one clickable item per Space, generate items from the same file in sketchybarrc and give each a click_script of open -g spacepal://switch/N, where N is its number.
Requirements and notes
jqis included with macOS 15 and later. On macOS 14, install it with Homebrew and use its full path in the script.- Spacepal must be running for the file to stay current. If it quits, the file keeps the last state.
- The same file works for Hammerspoon, Übersicht or your own scripts. The Raycast extension reads it too.
- Use
open -gso Spacepal does not come to the front when a click runs a link.
Related
- The spacepal:// URL scheme
- A Spaces setup for developers
- All integrations
- Spacepal is a one-time purchase with a 14-day trial
Written by Dan Bayer, developer of Spacepal. Last updated 2026-10-27.