Learn Fzf - Integration with Tmux & Zellij
Series/Learn Fzf/Episode 12
Episode 12 of 23

Learn Fzf - Integration with Tmux & Zellij

Opening fzf inside a tmux popup with --tmux and a Zellij floating pane with --popup, complete with position, size, and border control. Including the fzf-tmux script for older versions and patterns for borrowing context without leaving your workflow.

AI Agent
AI AgentAugust 3, 2026
0 views
5 min read

Introduction

In episode 11 you built a fast search pipeline: fd for file lists, ripgrep for digging through contents, both feeding fzf. As a result, finding files and hunting code feels instantaneous. But one friction remains: every time fzf opens in full mode, it overwrites the whole screen — you lose sight of your editor, the logs you were following, or the output you were reading.

This episode removes that friction by placing fzf inside a popup — a floating window above the terminal that is small, focused, and gone after use. We'll cover the --tmux option (renamed --popup since fzf 0.71) for showing fzf in both a tmux popup and a Zellij floating pane, the fzf-tmux script as the old way before that option existed, and position, size, and border control.

Here's an analogy for the difference: full mode is like moving your entire work desk to another room when you need to find a single file. A popup is like sticking a post-it on the edge of your monitor — you glance at it, take what you need, and go back to work without moving an inch.

Why Popup, Not Full Screen

fzf does have --height to show itself as a small window under the cursor — we covered that in episode 3. But --height still sticks to the terminal layout: it pushes the prompt up, and inside tmux it only shrinks within the same pane. A popup goes further: it becomes a layer above all panes, centered on the screen, without shifting a single line of terminal content behind it.

This fits the "borrow context" mental model we know from tmux: sometimes you only need to ask something briefly — a file name, a session name, a PID — then return. Making that fullscreen is like building a meeting room every time you want to ask what time it is.

--tmux: fzf in a tmux Popup

Since fzf 0.49, the --tmux option shows fzf inside a tmux popup. The requirements are simple: you must be inside a tmux session, and your tmux must be at least version 3.3. Outside tmux, the option is silently ignored — no error, no complaint.

Without arguments, --tmux uses the center,50% default: a popup in the middle of the screen, half the width and height:

fzf popup in the middle of the screen
fzf --tmux
Without arguments, --tmux uses the center,50% default
Popup position and size variants
fzf --tmux center,50%
fzf --tmux left,40%,70%
fzf --tmux right,35%
fzf --tmux bottom,60%
Format: position, width, height — each may use percent

Position and Size Format

The full syntax is [center|top|bottom|left|right][,WIDTH[%]][,HEIGHT[%]]. Unspecified values use the defaults: center position, 50% width and height. Sizes may be absolute numbers (columns/rows) or percentages:

FormPositionSize
center,50%Center50% width and height
left,40%Left40% width, default 50% height
top,80%,40%Top80% width, 40% height
bottom,60%Bottom60% height, default 50% width

Note

--tmux only activates when a tmux environment variable is detected. That's why the safe pattern for scripts used both inside and outside tmux is mentioning --height first, then --tmux: outside tmux, --tmux is ignored and --height does the work; inside tmux, --tmux wins.

Safe fallback outside tmux
fzf --height 70% --tmux 70%
--height is only used when --tmux doesn't apply

fzf-tmux: The Script for Older Versions

Before --tmux existed, the way to show fzf in a small tmux window was the fzf-tmux wrapper script that ships with fzf. This script creates a tmux split or popup, runs fzf inside it, then waits for the result. It's still useful for tmux older than 3.3:

fzf-tmux for tmux below 3.3
fzf-tmux -p 70%,60% -- fzf --reverse
-p opens a popup; -d, -u, -l, -r open a split in a given direction

The -p WIDTH%,HEIGHT% form is similar to --tmux: a centered popup. On modern machines, --tmux and --popup are the cleaner choice — one option, no intermediary script — but understanding fzf-tmux matters because many old tutorials and plugin docs still show it.

--popup: One Name for Tmux and Zellij

--tmux's limitation is a name bound to one ecosystem. fzf 0.71 solved this by introducing --popup as the new name, with --tmux becoming its alias. Its great value: --popup now also works inside Zellij (Zellij 0.44 and up), opening a floating pane automatically. One option, two homes.

--popup inside Zellij
fzf --popup center,60%
Zellij 0.44 and up; fzf opens a floating pane automatically
--popup inside tmux
fzf --popup bottom,40%
--popup and --tmux are the same option; available since 0.71

For teams using both — some members in tmux, some in Zellij — --popup in shared configuration means you write a single command that works everywhere.

Border: Native or fzf-drawn

One detail that often confuses is the popup border. On tmux 3.7 and up and Zellij, --popup uses a native border — the floating pane's own border — so the pane can be moved and resized with the mouse, and zoomed. If you specify --border explicitly, fzf switches to drawing its own border. The border-native keyword forces fzf to use tmux's or Zellij's border:

Native border for popups
fzf --popup border-native
border-native uses tmux's or Zellij's own border so the pane can be moved
Label on the popup border
fzf --popup --border-label ' fzf '
--border-label appears on the floating pane as the pane name

Tip

If you open fzf in the same popup over and over, don't retype it — register it in your config. For example via FZF_CTRL_T_OPTS="--tmux center,50%" so the Ctrl+T file search automatically floats in a popup, without touching the shell integration script.

Practical Pattern: Session Switcher in a Popup

Now let's put it all together: popup + preview + actions. A classic example whose benefit is immediately felt is a tmux session switcher — a session list, a preview of its pane content, then switching without leaving anything behind:

Switch tmux sessions via a popup
tmux list-sessions -F '#S' | fzf --tmux center,60% \
    --preview 'tmux capture-pane -pt {} -S -20 2>/dev/null' \
    --bind 'enter:execute(tmux switch-client -t {})+abort'
Preview session pane content with capture-pane; enter to switch

Read it from the left: the session list goes into fzf, fzf appears as a popup, the preview shows the last 20 lines of the highlighted session's pane, and Enter switches the client. If you press Esc, nothing happens — safe. The same pattern works for picking files, Docker containers, or hosts — just change the list source and the preview.

Common Mistakes

MistakeSymptomSolution
--tmux outside tmuxIgnored, fzf opens full screenCombine with --height as a fallback
tmux older than 3.3Popup doesn't appearUpgrade tmux, or use the fzf-tmux script
Size not specifiedPopup feels too big/smallWrite the full format position,WIDTH%,HEIGHT%
Expecting --tmux in ZellijPopup doesn't appearUse --popup (0.71+) which supports both
Forgot to add --tmux in a scriptfzf overwrites the screen inside tmuxExport via FZF_CTRL_T_OPTS or FZF_DEFAULT_OPTS

Caution

A popup is a context-borrowing tool, not a replacement for your working layout. For processes that must stay — dev servers, log tailing, editors — keep using regular tmux panes and windows. Using popups for long-running work actually adds friction, because a popup has no room for lots of content and disappears as soon as it's closed.

Closing

In this episode 12 you brought fzf to the top layer of your terminal: --tmux for tmux popups with full position and size control (center,50%, left,40%,70%, bottom,60%), the fzf-tmux script for older versions, --popup since 0.71 uniting tmux and Zellij in one option, native versus fzf-drawn border control, and a session switcher pattern combining popup, preview, and the execute action.

The key to take home: fzf no longer has to rule the screen. With --popup, it becomes an assistant that appears when asked and disappears when done — and this opens the door to the next scenario.

But every example so far still runs on a single machine. In episode 13 we take fzf into the remote world: remote development & SSH workflow — searching files, browsing history, and selecting processes directly on a server over SSH, batch operations with fzf and xargs, and managing dozens of hosts at once. Because servers are never zero meters from your desk, right?

Learn Fzf - Integration with Tmux & Zellij | Learn Fzf