Installation
This guide covers installing bspwm on various Linux distributions, from package managers to building from source. bspwm is a minimal window manager, so you'll also need companion tools for a complete desktop experience.
Understanding What You're Installing
bspwm follows the UNIX philosophy of doing one thing well. It only manages windows—it doesn't handle keybindings, status bars, or application launching. This means you'll need additional tools:
| Component | Purpose | Recommended Tools |
|---|---|---|
| Window Manager | Arrange and manage windows | bspwm |
| Hotkey Daemon | Keyboard shortcuts | sxhkd (same author as bspwm) |
| Compositor | Transparency, shadows, animations | picom, compton |
| Status Bar | System info, workspace indicators | polybar, lemonbar, tint2 |
| Launcher | Application menu | rofi, dmenu, wofi |
| Notification | Desktop notifications | dunst, mako |
| Wallpaper | Background image | feh, nitrogen, hsetroot |
This modular approach means you can swap any component without affecting the others.
Dependencies
Required Libraries
bspwm requires these X11/XCB libraries:
libxcb- X protocol C-language Bindingxcb-util- XCB utility librariesxcb-util-wm- Window manager utilities for XCBxcb-util-keysyms- Keysym utilities for XCB
These are typically installed automatically as dependencies when installing bspwm from a package manager.
Recommended Companion Software
For a functional desktop, you'll want at minimum:
- sxhkd - Simple X hotkey daemon (essential—without it, you have no keybindings)
- A terminal emulator - alacritty, kitty, urxvt, st, xterm
- A launcher - rofi or dmenu for launching applications
For a polished experience, also consider:
- picom - Compositor for transparency, shadows, and vsync (reduces screen tearing)
- polybar or lemonbar - Status bar showing workspaces, time, system info
- dunst - Notification daemon
- feh or nitrogen - Wallpaper setter
- xclip or xsel - Clipboard utilities
Package Installation
Arch Linux
# Essential
pacman -S bspwm sxhkd
# Recommended extras
pacman -S picom polybar rofi dunst feh alacritty
The Arch packages include example configuration files in /usr/share/doc/bspwm/examples/.
Debian / Ubuntu
# Essential
apt install bspwm sxhkd
# Recommended extras
apt install picom polybar rofi dunst feh
Note: Debian stable may have older versions. For newer releases, consider building from source or using backports.
Fedora
# Essential
dnf install bspwm sxhkd
# Recommended extras
dnf install picom polybar rofi dunst feh
openSUSE
# Essential
zypper install bspwm sxhkd
# Recommended extras
zypper install picom polybar rofi dunst feh
Gentoo
Gentoo provides fine-grained control through USE flags:
# Basic installation
emerge x11-wm/bspwm x11-misc/sxhkd
Available USE flags for bspwm:
| USE Flag | Description |
|---|---|
examples |
Install example configuration files (recommended for first-time users) |
doc |
Install documentation |
To enable USE flags, add to /etc/portage/package.use/bspwm:
x11-wm/bspwm examples doc
Then emerge:
emerge --ask x11-wm/bspwm x11-misc/sxhkd
Recommended companion packages for Gentoo:
emerge --ask x11-misc/picom x11-misc/polybar x11-misc/rofi x11-misc/dunst media-gfx/feh
Setting up the session:
Create a .desktop file for your display manager:
cat > /usr/share/xsessions/bspwm.desktop << 'EOF'
[Desktop Entry]
Name=bspwm
Comment=Binary space partitioning window manager
Exec=bspwm
Type=Application
EOF
Void Linux
# Essential
xbps-install -S bspwm sxhkd
# Recommended extras
xbps-install -S picom polybar rofi dunst feh
FreeBSD
# Essential
pkg install bspwm sxhkd
# Recommended extras
pkg install picom polybar rofi dunst feh
Alpine Linux
# Essential
apk add bspwm sxhkd
# Recommended extras
apk add picom polybar rofi dunst feh
NixOS
Add to your configuration.nix:
services.xserver.windowManager.bspwm = {
enable = true;
configFile = "/home/youruser/.config/bspwm/bspwmrc";
sxhkd.configFile = "/home/youruser/.config/sxhkd/sxhkdrc";
};
# Or for home-manager users
programs.bspwm = {
enable = true;
};
For a declarative configuration with home-manager:
xsession.windowManager.bspwm = {
enable = true;
monitors = {
eDP-1 = [ "I" "II" "III" "IV" "V" ];
};
settings = {
border_width = 2;
window_gap = 10;
focused_border_color = "#7aa2f7";
};
};
Building from Source
Building from source gives you the latest features and is required if your distribution doesn't package bspwm.
Prerequisites
Install build dependencies:
Debian/Ubuntu:
apt install build-essential git libxcb1-dev libxcb-util0-dev libxcb-keysyms1-dev libxcb-icccm4-dev libxcb-randr0-dev libxcb-xinerama0-dev libxcb-ewmh-dev libxcb-shape0-dev
Fedora:
dnf install gcc make git xcb-util-devel xcb-util-keysyms-devel xcb-util-wm-devel libxcb-devel
Arch:
pacman -S base-devel git libxcb xcb-util xcb-util-wm xcb-util-keysyms
Building bspwm
git clone https://github.com/baskerville/bspwm.git
cd bspwm
make
sudo make install
The default installation prefix is /usr/local. To install elsewhere:
make PREFIX=/usr install
Building sxhkd
git clone https://github.com/baskerville/sxhkd.git
cd sxhkd
make
sudo make install
Installing Example Configs
After building from source, manually copy examples:
mkdir -p ~/.config/bspwm ~/.config/sxhkd
cp /usr/local/share/doc/bspwm/examples/bspwmrc ~/.config/bspwm/
cp /usr/local/share/doc/bspwm/examples/sxhkdrc ~/.config/sxhkd/
chmod +x ~/.config/bspwm/bspwmrc
Updating
To update to the latest version:
cd bspwm
git pull
make clean
make
sudo make install
Then restart bspwm: bspc wm -r
Removal
If installed from source:
cd bspwm
sudo make uninstall
If installed from package manager, use the appropriate removal command (pacman -R, apt remove, etc.).
Initial Configuration
Create the configuration directories:
mkdir -p ~/.config/bspwm ~/.config/sxhkd
Copy the example configurations:
install -Dm755 /usr/share/doc/bspwm/examples/bspwmrc ~/.config/bspwm/bspwmrc
install -Dm644 /usr/share/doc/bspwm/examples/sxhkdrc ~/.config/sxhkd/sxhkdrc
Add to your ~/.xinitrc:
sxhkd &
exec bspwm
Essential Keybindings (default sxhkdrc)
| Keys | Action |
|---|---|
super + Return |
Open terminal |
super + space |
Program launcher |
super + Escape |
Reload sxhkd config |
super + alt + q |
Quit bspwm |
super + alt + r |
Restart bspwm |
super + w |
Close window |
super + {h,j,k,l} |
Focus window in direction |
super + {1-9} |
Switch to desktop |
Note: The default sxhkdrc uses urxvt as terminal. Edit to use your preferred terminal.
Multi-Monitor Setup
The default bspwmrc configures ten desktops on one monitor:
bspc monitor -d I II III IV V VI VII VIII IX X
For multiple monitors, configure each separately:
# Find monitor names
xrandr -q | grep " connected"
# Or: bspc query -M --names
# Configure desktops per monitor
bspc monitor HDMI-1 -d I II III IV V
bspc monitor eDP-1 -d VI VII VIII IX X
Setting Monitor Order
Explicitly set monitor order for consistent desktop indexing:
# Set order before configuring desktops
bspc wm -O HDMI-1 eDP-1
bspc monitor HDMI-1 -d I II III IV V
bspc monitor eDP-1 -d VI VII VIII IX X
Special Characters in Monitor Names
Escape names containing special characters with %:
bspc monitor %DVI-I-1.5 -d I II III IV V
Dynamic Monitor Configuration
Use conditionals in bspwmrc for different setups:
#!/bin/bash
if [[ $(xrandr -q | grep "HDMI-1 connected") ]]; then
xrandr --output HDMI-1 --primary --mode 1920x1080 --pos 0x0 \
--output eDP-1 --mode 1920x1080 --pos 1920x0
bspc wm -O HDMI-1 eDP-1
bspc monitor HDMI-1 -d I II III IV V
bspc monitor eDP-1 -d VI VII VIII IX X
else
bspc monitor eDP-1 -d I II III IV V VI VII VIII IX X
fi
Per-Host Configuration
#!/bin/bash
case "$HOSTNAME" in
desktop)
bspc wm -O DP-1 HDMI-1
bspc monitor DP-1 -d I II III IV V
bspc monitor HDMI-1 -d VI VII VIII IX X
;;
laptop)
bspc monitor eDP-1 -d I II III IV V VI VII VIII IX X
;;
esac
Updating sxhkdrc for Named Desktops
When using named desktops across monitors:
# Focus or send to desktop by name
super + {_,shift + }{1-9,0}
bspc {desktop -f,node -d} '{I,II,III,IV,V,VI,VII,VIII,IX,X}'
Panel Setup
Polybar
Add to your bspwmrc:
# Kill existing bars and start polybar
killall -q polybar
polybar mybar &
Reserve space for the bar:
bspc config top_padding 30
Lemonbar
The bspwm repository includes an example panel script:
cp /usr/share/doc/bspwm/examples/panel ~/.config/bspwm/
chmod +x ~/.config/bspwm/panel
Add to bspwmrc:
~/.config/bspwm/panel &
Autostart Applications
Add applications to bspwmrc:
#!/bin/sh
# Hotkey daemon
pgrep -x sxhkd > /dev/null || sxhkd &
# Compositor
picom &
# Notification daemon
dunst &
# Wallpaper
feh --bg-scale ~/Pictures/wallpaper.jpg &
# Panel
polybar mybar &
# ... rest of bspwm configuration
Complete Example Configuration
Here's a complete, well-commented bspwmrc suitable for a first-time user. This configuration provides a good starting point that you can customize.
Example bspwmrc
#!/bin/bash
#
# bspwmrc - bspwm configuration file
# This file is executed as a shell script on bspwm startup.
#
#
# ─── AUTOSTART ──────────────────────────────────────────────────────────────────
#
# Start the hotkey daemon (essential - without this, no keybindings work)
# The pgrep check prevents starting multiple instances on restart
pgrep -x sxhkd > /dev/null || sxhkd &
# Compositor for transparency, shadows, and vsync
# Remove if you don't want visual effects
pgrep -x picom > /dev/null || picom --config ~/.config/picom/picom.conf &
# Notification daemon
pgrep -x dunst > /dev/null || dunst &
# Set wallpaper
# Replace with your wallpaper path
~/.fehbg &
# Start polybar
# Kill any existing instances first to handle restarts cleanly
~/.config/polybar/launch.sh &
# Set cursor (X uses an ugly X cursor by default)
xsetroot -cursor_name left_ptr &
# Disable screen blanking (optional)
xset s off
xset -dpms
#
# ─── MONITOR CONFIGURATION ──────────────────────────────────────────────────────
#
# Detect connected monitors and configure accordingly
# This handles both single and multi-monitor setups
# Get list of connected monitors
MONITORS=($(xrandr --query | grep " connected" | cut -d" " -f1))
if [ ${#MONITORS[@]} -eq 1 ]; then
# Single monitor setup
bspc monitor "${MONITORS[0]}" -d 1 2 3 4 5 6 7 8 9 10
elif [ ${#MONITORS[@]} -eq 2 ]; then
# Dual monitor setup
# Adjust order based on your physical layout
bspc wm -O "${MONITORS[0]}" "${MONITORS[1]}"
bspc monitor "${MONITORS[0]}" -d 1 2 3 4 5
bspc monitor "${MONITORS[1]}" -d 6 7 8 9 10
else
# Fallback: configure the first monitor only
bspc monitor -d 1 2 3 4 5 6 7 8 9 10
fi
#
# ─── APPEARANCE ─────────────────────────────────────────────────────────────────
#
# Border width in pixels
bspc config border_width 2
# Gap between windows in pixels
bspc config window_gap 12
# Padding around the edges (space for panels, etc.)
bspc config top_padding 32 # Space for top bar
bspc config bottom_padding 0
bspc config left_padding 0
bspc config right_padding 0
# Border colors
bspc config normal_border_color "#44475a" # Unfocused windows
bspc config active_border_color "#6272a4" # Focused on inactive monitor
bspc config focused_border_color "#bd93f9" # Focused window
bspc config presel_feedback_color "#50fa7b" # Preselection indicator
#
# ─── BEHAVIOR ───────────────────────────────────────────────────────────────────
#
# Split ratio for new windows (0.5 = equal split)
bspc config split_ratio 0.52
# How new windows are inserted
# longest_side: split perpendicular to longest side (most intuitive)
# alternate: alternate between horizontal/vertical
# spiral: classic bspwm spiral pattern
bspc config automatic_scheme longest_side
# What to do when a window is removed
bspc config removal_adjustment true
# Focus behavior
bspc config focus_follows_pointer true # Hover to focus
bspc config pointer_follows_focus false # Don't warp cursor on focus change
bspc config pointer_follows_monitor true # Warp cursor when changing monitors
# Click behavior
bspc config click_to_focus button1 # Left click to focus
bspc config swallow_first_click false # Pass the focusing click to the app
# Pointer actions (mod + mouse button)
bspc config pointer_modifier mod4 # Super key
bspc config pointer_action1 move # Super + left click = move
bspc config pointer_action2 resize_side # Super + middle click = resize edge
bspc config pointer_action3 resize_corner # Super + right click = resize corner
#
# ─── MONOCLE MODE ───────────────────────────────────────────────────────────────
#
# Remove borders when in monocle (single window) mode
bspc config borderless_monocle true
# Remove gaps when in monocle mode
bspc config gapless_monocle true
# Keep padding (for bars) even in monocle mode
bspc config paddingless_monocle false
# Automatically use monocle when only one window exists
bspc config single_monocle false
#
# ─── EXTERNAL RULES ─────────────────────────────────────────────────────────────
#
# Path to external rules script (for complex dynamic rules)
# Uncomment and set path if you use external rules
# bspc config external_rules_command "$HOME/.config/bspwm/external_rules"
#
# ─── WINDOW RULES ───────────────────────────────────────────────────────────────
#
# Rules define automatic behavior for specific applications.
# Find window class with: xprop | grep WM_CLASS
#
# Floating applications
bspc rule -a Pavucontrol state=floating center=on
bspc rule -a Lxappearance state=floating center=on
bspc rule -a Arandr state=floating center=on
bspc rule -a Gpick state=floating center=on
bspc rule -a Nm-connection-editor state=floating center=on
bspc rule -a File-roller state=floating center=on
# Picture-in-picture (floating, sticky, always on top)
bspc rule -a "*:*:Picture-in-Picture" state=floating sticky=on layer=above
# Applications assigned to specific desktops
# bspc rule -a Firefox desktop='^2' follow=on
# bspc rule -a Code desktop='^3' follow=on
# bspc rule -a Spotify desktop='^10' follow=off
# Don't manage certain windows
bspc rule -a Conky state=floating manage=off
# Force some apps to tile even if they request floating
bspc rule -a Steam state=tiled
#
# ─── CLEANUP ────────────────────────────────────────────────────────────────────
#
# Adopt any orphaned windows from a previous session
bspc wm -o
# Notify that bspwm is ready (optional, for debugging)
# notify-send "bspwm" "Configuration loaded"
Example sxhkdrc
Here's a matching sxhkdrc with explanations:
#
# sxhkdrc - sxhkd configuration file
# Hotkey definitions for bspwm
#
#
# ─── WM CONTROL ─────────────────────────────────────────────────────────────────
#
# Quit bspwm
super + alt + q
bspc quit
# Restart bspwm (keeps windows, reloads config)
super + alt + r
bspc wm -r
# Reload sxhkd configuration
super + Escape
pkill -USR1 -x sxhkd; notify-send "sxhkd" "Configuration reloaded"
#
# ─── APPLICATIONS ───────────────────────────────────────────────────────────────
#
# Terminal
super + Return
alacritty
# Application launcher
super + space
rofi -show drun -show-icons
# Window switcher
super + Tab
rofi -show window -show-icons
# File manager
super + e
thunar
# Browser
super + b
firefox
#
# ─── WINDOW CONTROL ─────────────────────────────────────────────────────────────
#
# Close window
super + w
bspc node -c
# Kill window (force)
super + shift + w
bspc node -k
# Toggle window states
super + t
bspc node -t tiled
super + shift + t
bspc node -t pseudo_tiled
super + s
bspc node -t floating
super + f
bspc node -t fullscreen
# Toggle monocle layout
super + m
bspc desktop -l next
#
# ─── WINDOW FOCUS ───────────────────────────────────────────────────────────────
#
# Focus window in direction
super + {h,j,k,l}
bspc node -f {west,south,north,east}
# Focus next/previous window
super + {comma,period}
bspc node -f {prev,next}.local.!hidden.window
# Focus last window
super + grave
bspc node -f last
# Focus urgent window
super + u
bspc node -f any.urgent
#
# ─── WINDOW MOVEMENT ────────────────────────────────────────────────────────────
#
# Swap window in direction
super + shift + {h,j,k,l}
bspc node -s {west,south,north,east}
# Send window to desktop
super + shift + {1-9,0}
bspc node -d '^{1-9,10}'
# Send window to desktop and follow
super + ctrl + {1-9,0}
bspc node -d '^{1-9,10}' --follow
# Send to next/previous desktop
super + shift + {Left,Right}
bspc node -d {prev,next}.local --follow
#
# ─── DESKTOP CONTROL ────────────────────────────────────────────────────────────
#
# Focus desktop
super + {1-9,0}
bspc desktop -f '^{1-9,10}'
# Focus next/previous desktop
super + bracket{left,right}
bspc desktop -f {prev,next}.local
# Focus last desktop
super + BackSpace
bspc desktop -f last
#
# ─── PRESELECTION ───────────────────────────────────────────────────────────────
#
# Preselect direction
super + ctrl + {h,j,k,l}
bspc node -p {west,south,north,east}
# Preselect ratio
super + ctrl + {1-9}
bspc node -o 0.{1-9}
# Cancel preselection
super + ctrl + space
bspc node -p cancel
#
# ─── RESIZE ─────────────────────────────────────────────────────────────────────
#
# Expand window
super + alt + {h,j,k,l}
bspc node -z {left -20 0,bottom 0 20,top 0 -20,right 20 0}
# Contract window
super + alt + shift + {h,j,k,l}
bspc node -z {right -20 0,top 0 20,bottom 0 -20,left 20 0}
# Move floating window
super + {Left,Down,Up,Right}
bspc node -v {-20 0,0 20,0 -20,20 0}
# Balance all windows
super + equal
bspc node @/ -B
#
# ─── TREE MANIPULATION ──────────────────────────────────────────────────────────
#
# Rotate tree
super + r
bspc node @/ -R 90
# Flip tree horizontally/vertically
super + {_,shift +} y
bspc node @/ -F {horizontal,vertical}
#
# ─── LAYERS AND FLAGS ───────────────────────────────────────────────────────────
#
# Toggle sticky (window follows to all desktops)
super + shift + s
bspc node -g sticky
# Toggle hidden
super + shift + minus
bspc node -g hidden
# Show hidden windows
super + shift + plus
bspc node any.hidden.local -g hidden=off
# Toggle private (prevent auto-resize)
super + shift + p
bspc node -g private
First Login Checklist
After setting up bspwm for the first time, verify these work:
- Can you open a terminal? Press
Super + Return - Can you close it? Press
Super + w - Can you launch apps? Press
Super + Spacefor rofi/dmenu - Can you switch desktops? Press
Super + 1-9 - Can you move windows? Press
Super + Shift + h/j/k/l - Can you quit? Press
Super + Alt + q
If any of these fail, check:
- Is sxhkd running? Run
pgrep sxhkd - Is the terminal emulator installed? Check your sxhkdrc
- Check
~/.config/sxhkd/sxhkdrcfor syntax errors
See Troubleshooting for more help.
Next Steps
After installation, explore:
- Commands Reference - Learn all bspc commands
- Settings Reference - Customize appearance and behavior
- Window Rules - Automate window placement
- Technical Background - Understand the binary tree model
Join the community:
- IRC:
#bspwmon Libera.Chat - Reddit: r/bspwm
- GitHub: baskerville/bspwm