I recently added Hyprland, a dynamic Wayland compositor, to my Arch Linux setup without removing GNOME. I also wanted to manage all my Hyprland-related config files using my dotfiles repo, and I used stow
to keep things neat and modular.
This guide walks through:
- Installing Hyprland and its dependencies
- Keeping GNOME (via GDM)
- Managing config files via GNU Stow and a local dotfiles repo
π Prerequisites
- Youβre already running Arch Linux
- You have
GDM
(GNOME Display Manager) installed - You manage dotfiles using GNU Stow
- Your dotfiles live at
~/dotfiles
π§© Step 1: Install Hyprland + Essentials
Install Hyprland and some handy tools:
yay -S hyprland waybar swayosd-git \
xdg-desktop-portal-hyprland hyprpaper \
kitty dolphin thunar walker-bin nwg-look \
brightnessctl pavucontrol
π Step 2: Add Hyprland to GDM
Create a Wayland session file for GDM to recognize:
sudo tee /usr/share/wayland-sessions/hyprland.desktop > /dev/null <<EOF
[Desktop Entry]
Name=Hyprland
Comment=Hyprland Wayland Compositor
Exec=Hyprland
Type=Application
DesktopNames=Hyprland
EOF
β This adds "Hyprland" to the GDM login screen dropdown.
π Step 3: Organize Configs in Your Dotfiles
I'll assume your dotfiles are organized like this:
~/dotfiles/
hypr/
.config/hypr/hyprland.conf
waybar/
.config/waybar/config.jsonc
.config/waybar/style.css
swayosd/
.config/swayosd/config.toml
hyprpaper/
.config/hypr/hyprpaper.conf
Tip: This structure ensures
stow hypr
will create~/.config/hypr/...
etc.
Example swayosd/config.toml
:
[swayosd]
volume-step = 5
brightness-step = 5
Example hyprland.conf
for starters:
$mod = SUPER
bind = ,XF86AudioRaiseVolume, exec, swayosd-client --output-volume +5
bind = ,XF86AudioLowerVolume, exec, swayosd-client --output-volume -5
bind = ,XF86AudioMute, exec, swayosd-client --output-volume mute
bind = ,XF86MonBrightnessUp, exec, swayosd-client --brightness +5
bind = ,XF86MonBrightnessDown, exec, swayosd-client --brightness -5
# Load Walker launcher with Super+D
bind = $mod, D, exec, walker
# Reload config with Super+R
bind = $mod, R, exec, hyprctl reload
# Application bindings
$terminal = uwsm app -- kitty
$browser = flatpak run com.google.Chrome
$webapp = $browser --app
bind = SUPER, return, exec, $terminal
bind = SUPER, F, exec, uwsm app -- nautilus --new-window
bind = SUPER, B, exec, $browser
bind = SUPER, M, exec, uwsm app -- spotify
bind = SUPER, N, exec, $terminal -e nvim
bind = SUPER, T, exec, $terminal -e btop
bind = SUPER SHIFT, D, exec, $terminal -e lazydocker
bind = SUPER, G, exec, uwsm app -- signal-desktop
bind = SUPER, O, exec, uwsm app -- obsidian -disable-gpu
bind = SUPER, slash, exec, uwsm app -- 1password
bind = SUPER, A, exec, $webapp="https://chatgpt.com"
bind = SUPER SHIFT, A, exec, $webapp="https://grok.com"
bind = SUPER, Y, exec, $webapp="https://youtube.com/"
# Switch to workspace 1-5
bind = $mod, 1, workspace, 1
bind = $mod, 2, workspace, 2
bind = $mod, 3, workspace, 3
bind = $mod, 4, workspace, 4
bind = $mod, 5, workspace, 5
# Move focused window to workspace 1-5
bind = SUPER_SHIFT, 1, movetoworkspace, 1
bind = SUPER_SHIFT, 2, movetoworkspace, 2
bind = SUPER_SHIFT, 3, movetoworkspace, 3
bind = SUPER_SHIFT, 4, movetoworkspace, 4
bind = SUPER_SHIFT, 5, movetoworkspace, 5
# Navigate between windows (focus)
bind = $mod, h, movefocus, l
bind = $mod, l, movefocus, r
bind = $mod, k, movefocus, u
bind = $mod, j, movefocus, d
# Control tiling
bind = SUPER, J, togglesplit, # dwindle
bind = SUPER, P, pseudo, # dwindle
bind = SUPER, V, togglefloating,
bind = SHIFT, F11, fullscreen, 0
# Swap active window with the one next to it with mainMod + SHIFT + arrow keys
bind = SUPER SHIFT, h, swapwindow, l
bind = SUPER SHIFT, l, swapwindow, r
bind = SUPER SHIFT, k, swapwindow, u
bind = SUPER SHIFT, j, swapwindow, d
# Resize active window
bind = SUPER, minus, resizeactive, -100 0
bind = SUPER, equal, resizeactive, 100 0
bind = SUPER SHIFT, minus, resizeactive, 0 -100
bind = SUPER SHIFT, equal, resizeactive, 0 100
# Scroll through existing workspaces with mainMod + scroll
bind = SUPER, mouse_down, workspace, e+1
bind = SUPER, mouse_up, workspace, e-1
# Move/resize windows with mainMod + LMB/RMB and dragging
bindm = SUPER, mouse:272, movewindow
bindm = SUPER, mouse:273, resizewindow
# Close focused window with Super+W
bind = $mod, W, killactive,
# Force kitty to always tile
windowrulev2 = tile, class:^(kitty)$
# Force all Google Chrome windows to tile (including ChatGPT)
windowrulev2 = tile, class:^(Google-chrome)$
# Scroll faster in the terminal
windowrule = scrolltouchpad 1.5, class:Kitty
exec-once = hyprpaper &
exec-once = waybar &
exec-once = walker --gapplication-service &
π¦ Step 4: Stow Your Configs
From inside your ~/dotfiles repo:
cd ~/dotfiles
stow hypr
stow waybar
stow swayosd
stow hyprpaper
This will symlink the configs into ~/.config/
as expected.
π Step 5: Set Up Wallpaper (Optional)
In hyprpaper.conf
:
preload = ~/backgrounds/arch-mountains.png
wallpaper = eDP-1,~/backgrounds/arch-mountains.png
Adjust eDP-1 to match your display (run hyprctl monitors in Hyprland).
π Step 6: Log In to Hyprland
- Log out of GNOME
- At the GDM screen, click the gear icon βοΈ and select Hyprland
- Log in!
π§Ό Bonus: Environment Variables (Optional)
Add this to ~/.profile
or manage in your dotfiles:
export XDG_CURRENT_DESKTOP=Hyprland
export XDG_SESSION_TYPE=wayland
export GDK_BACKEND=wayland,x11
export QT_QPA_PLATFORM=wayland;xcb
π§ͺ Final Thoughts
With this setup:
- GNOME is still available
- Hyprland can be selected at login
- Your entire config is cleanly stowed in ~/dotfiles Iβll keep iterating on my dotfiles repo if you want to follow along.
Happy Hyprlanding π