Loading blogs…
Linux Desktop6 min read
Move your i3 setup to Sway on Arch without starting over: what carries over unchanged, what to rewrite (outputs, input, for_window), and the Wayland replacement for every X11 tool.
Full-stack engineer, New Delhi
Sway is a Wayland compositor built to accept i3's config format, so moving over is mostly a matter of copying one file. What actually takes time is the surrounding tools: xrandr, feh, picom, xclip, i3lock. None of them work on Wayland, and each one has a replacement.
This guide covers both parts. If you're still deciding whether to move at all, see Hyprland vs Sway vs i3.
You don't have to remove anything. Both can be installed together, and you choose at the login screen.
sudo pacman -S sway swaybg swayidle swaylock waybar \
foot fuzzel mako grim slurp wl-clipboard \
xdg-desktop-portal-wlr xorg-xwaylandxorg-xwayland lets your remaining X11-only apps keep running inside Sway.
mkdir -p ~/.config/sway
cp ~/.config/i3/config ~/.config/sway/config
sway --validatesway --validate (or -C) parses the config and exits, listing every line it doesn't understand. Fix those and you're most of the way there.
Add this line near the end. Arch's sway package puts a snippet in /etc/sway/config.d/ that exports WAYLAND_DISPLAY and XDG_CURRENT_DESKTOP=sway to systemd. Without it, screen sharing and the portal silently fail:
include /etc/sway/config.d/*Almost all the day-to-day config:
set $mod Mod4 and every bindsym / bindcodeworkspace_auto_back_and_forth, assignmode "resize" { … } and other modesgaps inner 8), borders, default_border pixel 2exec / exec_always, focus_follows_mouse, colours (client.focused …)split, layout tabbed, floating toggle, scratchpadDelete your exec xrandr … lines. Sway configures outputs itself:
# list connected outputs and their modes
swaymsg -t get_outputsoutput eDP-1 mode 1920x1200@60Hz pos 0 0 scale 1
output DP-1 mode 2560x1440@144Hz pos 1920 0
output * bg ~/Pictures/wall.jpg fillThe last line replaces feh --bg-fill. Sway calls swaybg for you. For a GUI, install wdisplays (the Wayland counterpart of arandr).
Fractional scaling works properly here (scale 1.25). It was hacky on X11.
# find device identifiers
swaymsg -t get_inputsinput type:keyboard {
xkb_layout us,de
xkb_options grp:alt_shift_toggle,caps:escape
repeat_delay 250
repeat_rate 40
}
input type:touchpad {
tap enabled
natural_scroll enabled
dwt enabled
}These replace setxkbmap, xset r rate and the xinput set-prop lines in your .xinitrc.
Native Wayland apps don't have an X11 class. They have an app_id:
# i3
for_window [class="pavucontrol"] floating enable
# sway (native Wayland app)
for_window [app_id="org.pulseaudio.pavucontrol"] floating enable
# sway (app still running under XWayland — class still works)
for_window [class="Steam"] floating enableTo find the right identifier, focus the window and run:
swaymsg -t get_tree | grep -E '"(app_id|class)"' | sort -uThe rules that break silently during a migration are almost always class rules for apps that became native Wayland apps.
i3bar's bar { status_command i3status } block works in Sway, which ships swaybar, and i3status runs unchanged. Most people move to Waybar for tray icons and styling:
bar {
swaybar_command waybar
}swaymsg takes the same commands and the same IPC JSON (-t get_workspaces, -t get_tree). Usually a search-and-replace is enough:
grep -rln "i3-msg" ~/.config ~/.local/bin | xargs sed -i 's/i3-msg/swaymsg/g'Python scripts built on i3ipc work against Sway as well.
| On i3 / X11 | On Sway / Wayland |
|---|---|
| xrandr, arandr | output in config, wdisplays |
| feh / nitrogen (wallpaper) | output * bg … (swaybg) |
| picom / compton | Not needed, Sway composites itself |
| i3lock | swaylock |
| xss-lock, xautolock | swayidle |
| dmenu / rofi | fuzzel, wmenu, or rofi 2.0+ (which supports Wayland) |
| xclip / xsel | wl-copy / wl-paste (wl-clipboard) |
| scrot, maim, flameshot | grim + slurp |
| xdotool | wtype (typing), ydotool (input), swaymsg (window control) |
| redshift | gammastep or wlsunset |
| dunst | Works on Wayland as-is, or use mako |
| urxvt / xterm | foot, kitty, alacritty (kitty and alacritty run on both) |
| setxkbmap, xinput, xset | input { … } blocks |
| .xinitrc / .xprofile | exec lines in the Sway config |
exec swayidle -w \
timeout 300 'swaylock -f -c 000000' \
timeout 330 'swaymsg "output * power off"' \
resume 'swaymsg "output * power on"' \
before-sleep 'swaylock -f -c 000000'
bindsym $mod+Escape exec swaylock -f -c 000000bindsym Print exec grim -g "$(slurp)" - | wl-copy
bindsym Shift+Print exec grim ~/Pictures/$(date +%F_%T).pngChoose Sway at your display manager, or from a TTY:
swayNVIDIA proprietary driver: Sway refuses to start on it and tells you to add --unsupported-gpu. It does run (create a custom session entry with Exec=sway --unsupported-gpu), but upstream won't help with bugs on that driver. If you're on NVIDIA and want official support, Hyprland is the more comfortable choice. See Hyprland on NVIDIA.
sway --validateinclude /etc/sway/config.d/*output, and setxkbmap/xinput with inputfor_window [class=…] rule against swaymsg -t get_treei3-msg → swaymsg in scriptsPut the new ~/.config/sway into your dotfiles so your next machine is one stow away.
Linux Desktop
An honest comparison of Hyprland, Sway and i3 — what tiling window managers are, who each suits, and a starter config to get going.
Linux Desktop
Screen sharing black, empty or missing on Hyprland? Work through the portal chain step by step — packages, services, the WAYLAND_DISPLAY race, permissions and XWayland apps.
Linux Desktop
Hyprland 0.55 moved to Lua configs and hyprlang is being dropped. A side-by-side cheat sheet for binds, rules, exec-once and env, plus the hyprctl dispatch gotcha.