Every keybind · every CLI flag · every layout primitive
| Alt+p | enter PANE mode (custom — Ctrl+P freed for nvim) |
| Ctrl+T | enter TAB mode |
| Ctrl+N | enter RESIZE mode |
| Ctrl+S | enter SCROLL mode |
| Alt+o | enter SESSION mode (custom — Ctrl+O freed for nvim jumplist) |
| Alt+h / Alt+l | previous / next zellij tab (custom — overrides default MoveFocusOrTab) |
| Alt+← / Alt+→ | MoveFocusOrTab — pane focus, crosses tab edge |
| Ctrl+G | enter LOCKED — all keys passthrough |
| Ctrl+Q | quit zellij & kill session |
<C-p> and <C-o>. Zellij tabs on Alt+h / Alt+l so Ctrl+H/L pass through to nvim window-direction & bash. Wezterm tabs moved to Ctrl+Alt+H / Ctrl+Alt+L.| n | new pane (auto direction) |
| d | split down (horizontal) |
| r | split right (vertical) |
| x | close focused pane |
| h j k l / arrows | move focus |
| p | cycle focus through panes |
| f | fullscreen toggle (zoom) |
| z | toggle pane frames |
| w | toggle floating panes |
| e | toggle embed ↔ float for focused pane |
| c | rename pane (Enter to commit) |
| i | toggle pinned (floating pane stays on top of all tabs) |
| n | new tab |
| x | close tab |
| r | rename tab |
| h l / arrows | previous / next tab |
| 1…9 | jump to tab N |
| s | toggle sync (input broadcast to all panes in tab) |
| b | break pane out into its own tab |
| ] / [ | move pane to next / previous tab |
| Tab | jump to most-recent tab |
| h j k l / arrows | shrink toward / grow away from that edge |
| + / - | grow / shrink uniformly |
| = | reset to even split |
| k / j | up / down one line |
| Ctrl+u / Ctrl+d | half-page up / down |
| PgUp / PgDn | full page up / down |
| e | open scrollback in $EDITOR |
| / | enter SEARCH submode |
| s | enter SEARCH submode (alt) |
| type then Enter | search forward |
| n / p | next / previous match |
| c | toggle case sensitivity |
| w | toggle whole-word |
| o | toggle wrap-around |
| d | detach (session keeps running) |
| w | session manager — list / switch / resurrect |
| c | configuration browser |
| p | plugin manager |
| a | about |
zellij attach NAME — everything resumes.| h j k l / arrows | move focused pane in that direction |
| n | move pane to next position (snake order) |
| p | move pane to previous position |
| Tab | cycle pane positions |
Every key is forwarded to the running program. Use this when you're inside vim, htop, tig, or anything that uses the same Ctrl-prefixed keys as zellij.
| Ctrl+G | unlock — return to NORMAL |
Some pane keys don't need PANE mode — Alt-prefixed shortcuts work from NORMAL:
| Alt+n | new pane |
| Alt+h/j/k/l | move focus |
| Alt+[ / Alt+] | previous / next pane (focus cycle) |
| Alt+f | toggle float |
| Alt+= / Alt+- | grow / shrink focused pane |
| Alt+i / Alt+o | move tab left / right |
zellij | start default session (or attach if one named $(zellij list-sessions) exists) |
zellij -s NAME | start a named session |
zellij attach NAME | attach to an existing session |
zellij attach -c NAME | attach, create if missing |
zellij attach -b NAME | attach in background (detaches first) |
zellij attach --force NAME | attach even if already attached (steals) |
zellij ls | list active & resurrectable sessions |
zellij list-sessions | same, long form |
zellij kill-session NAME | stop a specific session |
zellij kill-all-sessions | stop everything (prompts) |
zellij delete-session NAME | remove a serialized session from disk |
zellij delete-all-sessions | wipe all serialized sessions |
zellij --layout NAME | start with a named layout from ~/.config/zellij/layouts/ |
zellij --layout ./path.kdl | layout from a path |
zellij setup --dump-layout default | print built-in default layout |
zellij setup --dump-layout compact | print built-in compact layout |
zellij run -- CMD ARGS | open new pane running CMD (uses attached session) |
zellij run -d right -- CMD | open in a new right-split pane |
zellij run -f -- CMD | open as a floating pane |
zellij run -i -- CMD | close pane after CMD exits |
zellij edit FILE | open FILE in $EDITOR as a new pane |
zellij edit -f FILE | edit in a floating pane |
Send any keybind action from outside — great for scripts, polybar, sxhkd, i3 binds.
zellij action new-pane | split a new pane |
zellij action new-pane -d right | new vertical split (right) |
zellij action new-tab | new tab |
zellij action go-to-tab 2 | jump to tab 2 |
zellij action move-focus left|right|up|down | move focus |
zellij action close-pane | close focused pane |
zellij action toggle-pane-frames | show / hide pane borders |
zellij action rename-tab "build" | rename current tab |
zellij action write-chars "ls -la\n" | type into focused pane |
zellij action dump-screen FILE | dump current pane contents |
zellij setup --check | validate config + show paths |
zellij setup --dump-config | print full default config (KDL) |
zellij setup --generate-completion bash | generate shell completion |
zellij setup --generate-auto-start bash | snippet that auto-attaches on shell start |
zellij options --simplified-ui true | launch with simplified UI (no nerd-font glyphs) |
zellij --debug | log to /tmp/zellij-* |
zellij convert-config FILE | convert old YAML zellij config |
zellij convert-layout FILE | convert old YAML layout |
zellij convert-theme FILE | convert old YAML theme |
~/.config/zellij/config.kdl | main config |
~/.config/zellij/layouts/*.kdl | named layouts |
~/.config/zellij/themes/*.kdl | user themes |
~/.config/zellij/plugins/*.wasm | user plugins |
~/.cache/zellij/ | runtime cache |
~/.local/share/zellij/ | data: sessions, plugin store |
default_shell "bash" default_layout "compact" theme "catppuccin-mocha" pane_frames false simplified_ui false mouse_mode true on_force_close "detach" copy_command "xclip -selection clipboard" copy_on_select false scrollback_lines_to_serialize 10000
session_serialization true pane_viewport_serialization true serialize_pane_viewport true scrollback_lines_to_serialize 10000
zellij attach rebuilds them.Set theme "NAME". Bundled: default, dracula, gruvbox-dark, gruvbox-light, solarized-dark, tokyo-night, tokyo-night-storm, nightfox, catppuccin-mocha, catppuccin-frappe, catppuccin-macchiato, catppuccin-latte, everforest-dark, everforest-light + several more.
themes { tokyo-night-custom { fg 192 202 245 bg 26 27 38 black 15 15 20 red 247 118 142 // green, yellow, blue, magenta, cyan, white, orange } }
keybinds { normal { // Free Ctrl+P / Ctrl+O for nvim, expose them on Alt instead. unbind "Ctrl p" unbind "Ctrl o" bind "Alt p" { SwitchToMode "Pane"; } bind "Alt o" { SwitchToMode "Session"; } // Tab nav on Alt+h/l so Ctrl+H/L stay free for nvim & bash. bind "Alt h" { GoToPreviousTab; } bind "Alt l" { GoToNextTab; } } locked { bind "Ctrl g" { SwitchToMode "Normal"; } } }
normal pane tab resize scroll search session move locked tmux. shared_except and shared_among let you bind once across many. unbind removes a default before you replace it.SwitchToMode "Pane" | change mode |
NewPane "Down"|"Right" | split |
CloseFocus | close pane |
MoveFocus "Left" | focus |
Resize "Increase Left" | resize |
NewTab / GoToTab 1 | tabs |
ScrollUp / HalfPageScrollDown | scroll |
Detach / Quit | leave |
Run { cmd "htop"; cwd "/"; } | spawn command |
EditScrollback | open buffer in $EDITOR |
TogglePaneFrames / ToggleFloatingPanes | UI |
ToggleMouseMode | mouse on/off |
ui { pane_frames { rounded_corners true hide_session_name false } } show_startup_tips false show_release_notes false scroll_buffer_size 10000 styled_underlines true
A KDL file describing tabs and panes for a session. Launch with zellij --layout NAME — zellij looks in ~/.config/zellij/layouts/NAME.kdl then falls back to built-ins.
layout { pane }
One tab, one pane, your default shell. That's the cheapest valid layout.
layout { pane split_direction="vertical" { pane pane split_direction="horizontal" { pane pane } } }
split_direction on a parent dictates how its children are arranged.
pane size="70%" pane size=10 // rows or columns pane // no size = "fill remaining"
pane command="htop" pane command="watch" { args "-n" "1" "date" } pane command="nvim" cwd="~/dev/myproj" { args "+15" "src/main.rs" } pane edit="README.md"
command + args spawns a process. edit opens a file in $EDITOR. Both replace the default shell.layout { tab name="code" focus=true { pane size="70%" name="editor" pane split_direction="vertical" { pane name="shell" pane name="logs" } } tab name="scratch" { pane } }
~/.config/zellij/layouts/dev.kdl.layout { pane_template name="watcher" { pane command="watch" { args "-n" "2" "git" "status" } } tab { watcher pane } }
Define once, reference by name. tab_template works the same for tab structure.
layout { pane floating_panes { pane command="btm" { width "60%" height "60%" x "20%" y "20%" } } }
pane size=1 borderless=true { plugin location="zellij:status-bar" } pane size=2 borderless=true { plugin location="zellij:tab-bar" }
Built-in plugins: status-bar, tab-bar, compact-bar, strider, session-manager, configuration, plugin-manager, about.
Active session = running zellij process with at least one attached client. Detached = the process is alive, no client connected. Resurrectable = the process is gone but its serialized state is on disk; attach rebuilds it.
| create | zellij -s NAME or zellij attach -c NAME |
| attach | zellij attach NAME (or just zellij if one exists) |
| detach | Alt+o d (keeps process) |
| kill | zellij kill-session NAME or Ctrl+Q (ends process; serialized state may remain) |
| resurrect | zellij attach NAME against a resurrectable session |
| delete | zellij delete-session NAME (wipes serialized state) |
Open with Alt+o then w.
| ↑ ↓ | navigate sessions |
| Enter | switch to session (detaches current) |
| Ctrl+r | rename session |
| Ctrl+d | disconnect other clients from this session |
| Del | kill / delete session |
| Esc | close manager |
Two terminals can attach to the same session. Both see the same panes; input from either goes to the focused pane. Useful for pairing.
# terminal A zellij -s pair # terminal B (other person, or you SSHed in) zellij attach pair
~/.local/share/zellij/$VER/cache | plugin cache |
~/.cache/zellij/$VER/<session> | runtime, control sockets |
~/.local/share/zellij/$VER/sessions/<name> | serialized panes & scrollback (when session_serialization is on) |
zellij attach NAME.Optional. Add this to ~/.bashrc to make every wezterm tab attach to a single main session:
# Auto-attach to or create a zellij session called "main" # unless we're already inside zellij or in a non-interactive shell. if [[ -z "$ZELLIJ" ]] && [[ $- == *i* ]]; then zellij attach -c main fi
| config didn't reload | syntax error — run zellij setup --check |
| Ctrl+Q killed work | use Alt+o d to detach instead |
| Ctrl+O / Ctrl+P go to nvim | expected — this config rebound them to Alt+o / Alt+p so nvim keeps its jumplist and file-picker |
| vim key collisions | enter LOCKED mode with Ctrl+G |
| weird font glyphs | zellij options --simplified-ui true |
| scrollback lost on attach | set scrollback_lines_to_serialize 10000 (default 0) |
nothing on zellij ls after reboot | expected — runtime state is in /tmp; serialized state is on disk and resurrects via attach |