Polybar Status Bar Setup
Polybar is a highly customizable status bar for X window managers. This guide covers the complete configuration used with i3.
Overview
Configuration file: ~/.config/polybar/config.ini
Polybar provides system information, workspace indicators, and custom scripts in a sleek status bar.
Bar Configuration
Main Bar Setup
[bar/main]
monitor = ${env:MONITOR}
monitor-strict = false
override-redirect = false
width = 100%
height = 32
fixed-center = true
background = ${colors.background}
foreground = ${colors.foreground}
border-top-size = 0
border-bottom-size = 0
padding = 2
module-margin-left = 1.5
module-margin-right = 1.5
line-size = 1
bottom = false
Module Layout
modules-left = spotify xwindow pulseaudio
modules-center = i3
modules-right = tray network memory-mb cpu date time xbacklight wlan battery
Modules are organized into three sections: left, center, and right of the bar.
Font Configuration
font-0 = "JetBrainsMonoNL Nerd Font:style=Regular:size=9;3"
font-1 = "JetBrainsMonoNL Nerd Font:style=Bold:size=9;3"
font-2 = "JetBrainsMonoNL Nerd Font:style=Italic:size=9;3"
Nerd Fonts are required for icon rendering. Install JetBrainsMono Nerd Font or adjust to your available fonts.
i3 Workspace Module
Basic Configuration
[module/i3]
type = internal/i3
pin-workspaces = true
index-sort = true
wrapping-scroll = false
format = <label-state> <label-mode>
fuzzy-match = true
Workspace Icons
Roman Numeral Style (Active)
ws-icon-0 = 0 ;0
ws-icon-1 = 1 ;I
ws-icon-2 = 2 ;II
ws-icon-3 = 3 ;III
ws-icon-4 = 4 ;IV
ws-icon-5 = 5 ;V
ws-icon-6 = 6 ;VI
ws-icon-7 = 7 ;VII
ws-icon-8 = 8 ;VIII
ws-icon-9 = 9 ;IX
ws-icon-10 = 10 ;X
ws-icon-11 = 11 ;Ms
ws-icon-12 = 12 ;Teams
ws-icon-13 = 13 ;Front
ws-icon-14 = 14 ;Back
ws-icon-20 = 20 ;
Alternative Icon Styles (Commented)
Workspace Styling
# Focused workspace
label-focused = ${self.workspace-label}
label-focused-foreground = ${colors.background-dark}
label-focused-underline = ${colors.hover}
label-focused-background = ${colors.hover}
label-focused-padding = 2
# Unfocused workspaces
label-unfocused = ${self.workspace-label}
label-unfocused-padding = 2
# Visible on other monitors
label-visible = ${self.workspace-label}
label-visible-foreground = ${self.label-focused-foreground}
label-visible-underline = ${self.label-focused-underline}
label-visible-background = ${self.label-focused-background}
label-visible-padding = 2
# Urgent workspaces
label-urgent = ${self.workspace-label}
label-urgent-background = ${colors.color5}
label-urgent-foreground = ${colors.color15}
label-urgent-padding = 2
System Monitoring Modules
CPU Module
[module/cpu]
type = internal/cpu
interval = 0.5
format = <label>
format-padding = 1
format-underline = ${colors.underline}
format-prefix = " "
label = %percentage%%
Memory Module
[module/memory-mb]
type = custom/script
exec = free -m | awk '/^Mem:/ {printf "%.1f \n ", $3/1000}'
interval = 1
format = <label>
format-padding = 1
format-underline = ${colors.underline}
format-background = ${colors.background}
format-prefix = " "
label = %output% GB
[module/memory]
type = internal/memory
interval = 0.5
format-prefix-foreground = ${colors.color15}
format-padding = 1
format-underline = ${colors.underline}
format-background = ${colors.background}
format-prefix = " "
label = %{T2}%percentage_used%%%{T-}%
Temperature Module
[module/temperature]
type = internal/temperature
thermal-zone = 0
interval = 0.5
base-temperature = 45
warn-temperature = 70
format-prefix = " "
format = <label>
format-warn = <label-warn>
format-padding = 1
format-underline = ${colors.underline}
label = %temperature-c%
label-warn = %temperature-c%
label-warn-foreground = ${colors.color1}
Adjust thermal-zone based on your system. Find available zones with: ls /sys/class/thermal/
Network Module
[module/network]
type = internal/network
interface = enp6s0
interval = 2.0
format-connected-underline = ${colors.underline}
label-connected = %netspeed%
label-disconnected = not connected
label-disconnected-foreground = #66ffff
ramp-signal-0 =
ramp-signal-1 =
ramp-signal-2 =
ramp-signal-3 =
ramp-signal-4 =
Change interface = enp6s0 to match your network interface name. Find it with: ip link
Audio Module
[module/pulseaudio]
type = internal/pulseaudio
format-volume = <ramp-volume> <label-volume>
label-volume = "%percentage%%"
label-volume-padding = 1
ramp-volume-0 =
ramp-volume-1 =
ramp-volume-2 =
format-muted = <label-muted>
format-muted-prefix = ""
format-muted-prefix-padding = 1
label-muted = %percentage%%
label-muted-padding = 1
click-right = pavucontrol&
Right-click the volume module to open PulseAudio Volume Control (pavucontrol).
Battery Module
[module/battery]
type = internal/battery
battery = BAT0
adapter = AC0
full-at = 98
format-padding = 1
format-underline = ${colors.underline}
# Discharging state
format-discharging = <ramp-capacity> <label-discharging>
label-discharging = " %{T2}%percentage%%%{T-}"
ramp-capacity-0 =
ramp-capacity-1 =
ramp-capacity-2 =
ramp-capacity-3 =
ramp-capacity-4 =
ramp-capacity-5 =
ramp-capacity-6 =
ramp-capacity-7 =
ramp-capacity-8 =
ramp-capacity-9 =
ramp-capacity-0-foreground = ${colors.color1}
# Charging state
format-charging = <animation-charging> <label-charging>
label-charging = " %{T2}%percentage%%%{T-}"
animation-charging-framerate = 800
animation-charging-foreground = ${colors.color4}
# Full state
format-full = <label-full>
format-full-prefix = " "
format-full-prefix-foreground = ${colors.color4}
label-full = %{T2}%percentage%%%{T-}
Date and Time Modules
Date Module
[module/date]
type = internal/date
interval = 1.0
time = "%m/%d"
time-alt = "%A, %B %d"
format-underline = ${colors.underline}
format-background = ${colors.background}
format-padding = 1
format-prefix = " "
label = %{T2}%time%%{T-}
Time Module
[module/time]
type = internal/date
interval = 1
time = "%H:%M"
time-alt = "%H:%M:%S"
format = <label>
format-underline = ${colors.underline}
format-padding = 1
format-prefix = " "
label = %{T2}%time%%{T-}
Click on date/time modules to toggle between display formats.
Custom Modules
Spotify Module
[module/spotify]
type = custom/script
exec = ~/dotfiles/.config/polybar/scripts/spotify.py
interval = 1
format = <label>
format-prefix = ""
format-prefix-foreground = #1DB954
format-padding = 2
format-background = ${colors.background}
format-foreground = ${colors.color15}
format-underline = ${colors.color15}
label = %output:0:150%
Requires a custom Python script at ~/dotfiles/.config/polybar/scripts/spotify.py to fetch Spotify track info.
Window Title Module
[module/xwindow]
type = internal/xwindow
format-prefix = ""
label = %{T2}%title%%{T-}
label-maxlen = 24
label-empty = Desktop
label-empty-foreground = #707880
format-foreground = ${colors.foreground}
format-underline = ${colors.underline}
format-background = ${colors.background}
format-padding = 1
System Tray
[module/tray]
type = internal/tray
format-margin = 2px
tray-padding = 2px
tray-spacing = 4px
tray-size = 12px
Backlight Control
[module/xbacklight]
type = internal/xbacklight
output = DP-4
format = <label> <bar>
label =
bar-width = 10
bar-indicator = |
bar-indicator-foreground = #fff
bar-indicator-font = 2
bar-fill = ─
bar-fill-font = 2
bar-fill-foreground = #9f78e1
bar-empty = ─
bar-empty-font = 2
bar-empty-foreground = ${colors.foreground}
Launching Polybar
Launch Script
Create ~/.config/polybar/launch.sh:
#!/usr/bin/env bash
# Terminate already running bar instances
killall -q polybar
# Wait until the processes have been shut down
while pgrep -u $UID -x polybar > /dev/null ; do sleep 1 ; done
# Launch Polybar for each monitor
if type "xrandr" ; then
for m in $( xrandr --query | grep " connected" | cut -d " " -f1 ); do
MONITOR = $m polybar --reload main &
done
else
polybar --reload main &
fi
echo "Polybar launched..."
Make it executable:
chmod +x ~/.config/polybar/launch.sh
Auto-start with i3
Add to i3 config:
exec_always --no-startup-id $HOME /.config/polybar/launch.sh
Color Themes
Polybar uses a separate colors file:
include-file = ~/dotfiles/.config/polybar/theme/colors.ini
Create your color scheme in colors.ini:
[colors]
background = #1e1e2e
background-dark = #11111b
foreground = #cdd6f4
hover = #89b4fa
underline = #89dceb
color1 = #f38ba8
color4 = #94e2d5
color5 = #f9e2af
color15 = #ffffff
Testing and Debugging
Test configuration syntax:
Run in foreground to see errors:
journalctl -f --user-unit=polybar
Invalid module names or missing scripts will prevent Polybar from starting. Check error messages carefully.
Advanced Configuration
IPC Support
Enables polybar-msg for runtime control:
polybar-msg cmd toggle
polybar-msg cmd show
polybar-msg cmd hide
Module-Specific Actions
Many modules support click actions:
click-left = command
click-middle = command
click-right = command
scroll-up = command
scroll-down = command
Example usage in the network module to open network settings on click.