This is going to be a "quick" little guide to customizing the tmux status bar to include a scrolling Spotify “Now Playing” widget. I’m going to be doing this on macOS, but you should be able to adapt it to Linux and I'll try to assist where I can. If you’re on Windows… I have no idea. Here are the tools we’re going to use:
tmux - Kind of obvious. I’m assuming you already have this.
spotify-tui - We’ll mostly just be using this for the spt playback CLI command to get the playback info.
spotifyd- We need this for the “song changed” hook and so we don’t need the Spotify app open.
bash - You already know.
homebrew - Skip this if you’re not on macOS. I’ll be using it to download all of these tools and also to launch the spotifyd daemon. Again, I’m going to assume you already have this.
Spotify - You'll probably need this, eh? I'm pretty sure you need Spotify Premium for this to work, but I'm not positive.
Prerequisites
Before we get started, go make a Spotify developer account if you don’t already have one. Then create a new app in the developer dashboard. The name and description don’t matter, but make sure you add http://localhost:8888/callback to the "Redirect URIs" section - spotify-tui requires this and we’ll revisit it later.
Now let’s get our tools. If you're on macOS, use the following command:
brew install spotify-tui
brew install spotifyd
For Linux users, you can install the tools using your package manager or by following the instructions on their respective GitHub repositories (spotify-tui and spotifyd).
Creating the Script
Now we can get a little crazy with some bash scripting. We’re going to gloss over this, but essentially it uses the spt playback subcommand from spotify-tui to get the current song in a specified format, then uses the current date in seconds to calculate the scroll position if the playback info is longer than a certain number of characters. It does some tempfile file things to store the state and saves us from calling the Spotify API too many times.
Save this script anywhere you want but let’s name it spt_status.sh.
#!/usr/bin/env bash
tmpdir="$TMPDIR/spt_status"
data_file="$tmpdir/current.txt"
if [ ! -d "$tmpdir" ]; then
printf "\rInitializing..."
mkdir "$tmpdir"
echo "null" >"$data_file"
echo "false" >>"$data_file"
printf "\rInitialized successfully!"
exit 0
fi
output=$(head -n 1 "$data_file" 2>/dev/null)
updated=$(tail -n 1 "$data_file" 2>/dev/null)
if [ "$1" = "--update" ]; then
printf "\rUpdating..."
if [ "$updated" != "true" ]; then
echo "null" >"$data_file"
echo "true" >>"$data_file"
fi
exit 0
fi
output=$(head -n 1 "$data_file" 2>/dev/null)
if [ "$output" = "null" ]; then
pb=$(/usr/local/bin/spt playback --format "%s %a: %t" 2>/dev/null || echo "null")
echo "$pb" >"$data_file"
echo "false" >>"$data_file"
output=$(head -n 1 "$data_file" 2>/dev/null)
fi
output=$(echo "$output" | tr -d '\n')
max_length=35
scroll_speed=10
if [ "$output" = "null" ]; then
printf "\rSomething went wrong..."
exit 1
fi
if [ ${#output} -gt $max_length ]; then
current_time=$(date +%s)
play_pause_symbol="${output:0:2}"
output=${output:2}
scroll_position=$((current_time * scroll_speed % (${#output} + max_length)))
padded_output="${output}$(printf '%*s' $((max_length)) '')${output}"
displayed_output="${padded_output:$scroll_position:(($max_length - 2))}"
printf "\r%s%s " "$play_pause_symbol" "$displayed_output"
exit 0
fi
padded_output="${output}$(printf '%*s' $((max_length + 1 - ${#output})) '')"
printf "\r%s" "$padded_output"
Make sure you run chmod +x spt_status.sh to make it executable.
Configuring the Daemon
Now, we’re almost ready to see it in action, but there are a couple of things we need to do first.
For macOS users, we’ll make a small modification to the .plist file that brew uses to launch the daemon. Open up /usr/local/Cellar/spotifyd/0.3.4/homebrew.mxcl.spotifyd.plist (modify to match your version) and look for this section around line 17:
<key>ProgramArguments</key>
<array>
<string>/usr/local/opt/spotifyd/bin/spotifyd</string>
<string>--no-daemon</string>
<string>--backend</string>
<string>portaudio</string>
</array>
Add the following to the array after <string>portaudio</string>:
<string>--on-song-change-hook</string>
<string>/path/to/spt_status.sh --update</string>
Note that this needs to be the full path to our script.
For Linux users, you can create a systemd service file to launch the daemon. Create a file named spotifyd.service in ~/.config/systemd/user/ with the following content:
[Unit]
Description=Spotifyd Daemon
[Service]
ExecStart=/usr/bin/spotifyd --no-daemon --backend alsa --on-song-change-hook "/path/to/spt_status.sh --update"
Restart=always
RestartSec=12
[Install]
WantedBy=default.target
Replace /path/to/spt_status.sh with the full path to the script you created earlier.
Launching the Daemon
From here, we can launch our daemon:
For macOS users:
brew services start spotifyd
For Linux users:
systemctl --user enable --now spotifyd.service
Configuring spotify-tui and tmux
We need to run spt one time to configure it, so do that now and follow the messages, entering your Spotify app’s client and secret tokens when prompted. Then press d and select spotifyd from the devices list. If it’s not showing up in the list of available devices, you might need to open the official app and select “spotifyd” as your playback device. You can then close the Spotify app.

We’re almost there, I promise. All that’s left is to open up your tmux config (probably at ~/.tmux.conf) and make a couple of small tweaks:
set -g status-interval 1
set -g status-right ' #(spt_status.sh)'
Wrapping Up
Whew! We did it. If you have any open tmux sessions, exit them with tmux kill-server and start up a new one. Play a song with either the official app or with spotify-tui, and you should see our new widget on the right.
If you liked this, let me know in the comments and give me a follow! Also, don’t hesitate to let me know if something isn’t working or if I overlooked anything.
I'm also on Twitter @techsavvytravvy and sometimes I stream on Twitch - come hang out!
Bye!