What Is fzf?
fzf is a command-line fuzzy finder. You pipe any list of items into it, type a few characters, and it instantly filters to matching results. Select one, it gets returned to your shell.
That sounds simple. In practice, it changes how you interact with everything in the terminal.
Installation
# macOS
brew install fzf
$(brew --prefix)/opt/fzf/install # Install key bindings and completions
# Linux
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
# Ubuntu/Debian
sudo apt install fzf
The Three Built-In Shell Integrations
After install, these key bindings work in your shell:
Ctrl+R โ Fuzzy Command History
The killer feature. Instead of pressing โ 20 times to find a command:
Press Ctrl+R, type "docker run" or "npm test" or any fragment
โ instantly filters your entire command history
โ press Enter to run it
This alone is worth the install.
Ctrl+T โ Fuzzy File Finder
Press Ctrl+T in your shell
โ fzf opens showing all files recursively
โ type to filter, Enter to insert the path into your command
Use it mid-command:
vim [Ctrl+T] # fuzzy find the file you want to edit
cat [Ctrl+T] # fuzzy find a file to cat
Alt+C โ Fuzzy cd
Press Alt+C
โ fuzzy find a directory to cd into
โ Enter jumps there
Using fzf in Your Own Scripts
fzf reads from stdin and writes the selection to stdout:
# Select a file and open it
vim $(find . -name "*.ts" | fzf)
# Select a branch and check it out
git checkout $(git branch | fzf)
# Select a running process and kill it
kill $(ps aux | fzf | awk '{print $2}')
# Select a docker container and get a shell
docker exec -it $(docker ps --format "{{.Names}}" | fzf) /bin/sh
The Preview Window
fzf can show a preview of each item as you select:
# Preview file contents as you browse
fzf --preview 'bat --color=always {}'
# Preview git log entry
git log --oneline | fzf --preview 'git show {1} --stat'
Useful fzf Aliases and Functions
Add these to your ~/.bashrc or ~/.zshrc:
# Interactive git branch checkout
gco() {
local branch
branch=$(git branch -a | grep -v HEAD | fzf --height 40% --preview 'git log --oneline -10 {}')
git checkout $(echo "$branch" | sed 's/remotes\/origin\///')
}
# Kill a process interactively
fkill() {
local pid
pid=$(ps aux | fzf | awk '{print $2}')
[ -n "$pid" ] && kill -9 "$pid" && echo "Killed $pid"
}
# Open file with default editor
fe() {
local file
file=$(find . -type f | fzf --preview 'bat --color=always {}')
[ -n "$file" ] && ${EDITOR:-vim} "$file"
}
# cd to a directory anywhere in the tree
fcd() {
local dir
dir=$(find . -type d | fzf)
[ -n "$dir" ] && cd "$dir"
}
# Search command history with full preview
fh() {
eval $(history | fzf --tac | sed 's/ *[0-9]* *//')
}
fzf + ripgrep: Live Search
Combine fzf and ripgrep for interactive code search:
# Add to .bashrc/.zshrc
rgs() {
rg --color=always --line-number "$1" | \
fzf --ansi \
--delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}' \
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3'
}
# Usage: rgs "useState"
# โ live filtered results with file preview
fzf Options Reference
fzf \
--height 40% # Don't take up full screen
--layout reverse # Show results from top
--border # Draw a border
--preview 'bat {}' # Preview command
--multi # Allow multiple selections (Tab to mark)
--query "initial" # Pre-fill the search query
--filter "pattern" # Non-interactive filtering
Key Takeaways
Ctrl+Rfor history,Ctrl+Tfor files,Alt+Cfor directories โ these alone justify the install- Pipe any list to
fzf, get the selection back โ works with any command - Add
--previewwithbatfor file previews while browsing - Combine with
ripgrepfor interactive codebase search with syntax-highlighted previews - Write functions that wrap
fzffor your most common workflows (git checkout, kill process, etc.)