CLI tool
junegunn/fzf avatar
junegunn/fzf

fzf: The General-Purpose Command-Line Fuzzy Finder

fzf is an interactive command-line fuzzy finder that filters files, command history, processes, and other text streams.

83,244 stars3,605 forksGoMIT

At a glance

What is it?
fzf is a fast, single-binary fuzzy finder for the command line that filters files, shell history, processes, and any text stream through an interactive terminal interface. MIT licensed and available on macOS, Linux, and Windows, it ships with built-in integrations for Bash, Zsh, Fish, Nushell, Vim, and Neovim.
Who is it for?
fzf suits developers who spend meaningful time in a terminal and want interactive selection over files, history, and process lists without writing custom menus. The shell integrations for Bash, Zsh, Fish, and Nushell are the fastest entry point; run brew install fzf and then follow the shell integration instructions in the README before investing time in custom workflows.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 8 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What fzf does and who uses it

The README describes fzf as a general-purpose command-line fuzzy finder and an interactive terminal toolkit. It is not limited to file search. The README lists the use cases explicitly: selecting files, browsing command history, previewing data, navigating complex datasets with fuzzy matching, and creating custom menus and workflows. The underlying model is simple: fzf reads lines from standard input, displays them in an interactive terminal UI, filters them as the user types, and writes the selection to standard output.

Because the input and output are plain text, fzf composes with any command that produces lines and any command that accepts them. Shell users apply it to cd navigation, git branch and commit selection, process management, and log filtering. Vim and Neovim users invoke it via the bundled plugin to select buffers, files, and tags within the editor.

The README describes the target architecture as batteries-included: rather than requiring users to configure everything, fzf ships with ready-to-use shell integrations for Bash, Zsh, Fish, Nushell, Vim, and Neovim. This reduces the setup to installing the binary and running a shell integration script.

How fzf filters and ranks candidates

fzf's fuzzy matching algorithm accepts a search query and scores each input line against it. The scoring prioritizes consecutive character matches and matches near the beginning of a word, so typing `brs` would rank `browse` and `branch` above a line where b, r, and s are far apart. The README notes that fzf is optimized to process millions of items in milliseconds.

The README describes several search syntax modes that users can mix in a single query. A plain term uses fuzzy matching. Prefixing a term with a single quote switches to exact substring matching. A caret prefix anchors the match to the beginning of the line, and a dollar sign anchors to the end. A slash prefix applies a regex match. Multiple terms are AND-combined by default; a pipe character separates OR conditions.

The `--nth` option limits matching to specific fields within each line, and `--delimiter` controls the field separator. This makes fzf usable with structured input like process tables or log lines where only a portion of each line should be searched.

Installing fzf on macOS, Linux, and Windows

The README lists multiple installation methods. On macOS, the preferred approach is Homebrew:

sh
brew install fzf

On macOS, fzf is also available via MacPorts. The README notes both options. Using Mise for version management is also documented:

sh
mise use -g fzf@latest

On Linux, the README provides a table of package manager commands. For Debian and Ubuntu:

sh
sudo apt install fzf

For Fedora: `sudo dnf install fzf`. For Arch Linux: `sudo pacman -S fzf`. For Alpine: `sudo apk add fzf`. For NixOS: `nix-env -iA nixpkgs.fzf`.

On Windows, fzf is available via Chocolatey, Scoop, Winget, and MSYS2. The README's Windows table shows:

sh
winget install fzf

For those who want to use the latest commit rather than a packaged release, the README documents a git clone installation path that uses `make install`. Binary releases are also available from the GitHub releases page.

After installation, an important note from the README: Homebrew and most package managers install the binary but do not automatically configure shell integration. The README explicitly flags that users must follow a separate shell integration setup step.

Shell integration, key bindings, and fuzzy completion

fzf's shell integration adds three key bindings and a fuzzy completion trigger. The README documents this for Bash, Zsh, Fish, and Nushell. Running the bundled install script with `--all` sets up all supported integrations at once, as shown in the repository's Dockerfile:

sh
./install --all

Once shell integration is active, CTRL-T pastes selected files and directories into the command line. CTRL-R replaces the default reverse-history search with an interactive fuzzy search over the full command history. ALT-C changes the current directory by fuzzy-selecting from subdirectories.

Fuzzy completion works with a double-asterisk trigger. Typing `vim ` followed by the trigger and pressing Tab opens fzf pre-populated with the file system, so the user can fuzzy-filter to a file and press Enter to complete the argument. The trigger extends to other commands: typing it after `ssh` opens fzf over known hostnames, after `export` over environment variables, and after `kill` over process IDs.

For Bash specifically, the README lists which commands support fuzzy completion by default, and describes how to write custom completion source functions for any command not in the built-in list.

Preview windows and display modes

fzf supports a preview window that shows additional context for each highlighted item. The `--preview` option takes a shell command that receives the current candidate and produces output to display in a pane alongside the main selection list. A typical use is showing file contents while browsing filenames.

The README describes two display modes beyond the default full-screen layout. The `--height` mode constrains fzf to a fraction of the terminal height, keeping the shell prompt visible above. The `--popup` mode renders fzf in a floating overlay using the terminal multiplexer's popup capability.

Image previewing is documented as a capability when using a terminal that supports the Kitty graphics protocol or similar image rendering, with `--preview` invoking a dedicated image preview command. The README's fzf Theme Playground link points to an external tool for generating `--color` configurations without manual construction.

The preview window supports scrolling with SHIFT-UP and SHIFT-DOWN. The pane can appear above, below, left, or right of the selection list, controlled by the `--preview-window` position argument.

Event-driven architecture for custom workflows

The README describes fzf as programmable: it exposes an event-driven architecture for building custom terminal interfaces. Users bind shell commands to key events using the `--bind` option. A bound command can reload the candidate list, transform the query, execute external programs, or navigate the selection.

The README shows three examples of reloading the candidate list. The first updates the process list when CTRL-R is pressed, so that the list reflects processes created after fzf opened. The second switches between two input sources, files or directories, on CTRL-D and CTRL-F. The third integrates ripgrep for live interactive search: typing updates a ripgrep query and reloads the file list with matching results, effectively building an interactive grep UI inside fzf.

The `--bind` system also supports actions such as executing a program with the selected item, transforming the query string, or navigating to a previous or next entry. The README's Advanced Topics section documents the action vocabulary and the reload mechanism, including the `become` action that replaces the fzf process with a different process once a selection is made.

fzf versus skim and basic shell completion

skim (sk) is a Rust reimplementation of fzf with a broadly compatible interface. The two tools share the same basic model: pipe lines in, type to filter, press Enter to select. skim is the closest alternative in terms of feature surface. The implementation language differs (Go for fzf, Rust for skim), and feature parity is not exact, but for most standard uses the behavior is interchangeable. fzf is older, more widely packaged, and the README's shell integration scripts cover more shells than skim does.

Compared to native Bash or Zsh tab completion without fzf, the difference is interactive filtering. Standard tab completion expands a prefix match and presents a list to cycle through. fzf replaces the cycling with a full interactive fuzzy search that handles long lists and non-prefix matches without requiring the user to type a longer prefix.

The README notes that fzf respects .gitignore when paired with a compatible file finder, and documents that using ripgrep or fd as the FZF_DEFAULT_COMMAND value provides a faster file list than the default find-based one. This composability is where fzf differs from standalone file managers: it adds interactive selection to whatever command the user already uses for listing.

Maintenance record, licensing, and Vim plugin

The last push to the fzf repository landed on 2026-09-21. Release v0.74.4 was published on 2026-09-12, with v0.74.3 on 2026-08-17 and v0.74.2 on 2026-08-01. The release cadence shows regular updates.

fzf is licensed under the MIT license. The Vim plugin bundled in the plugin/ directory is part of the same repository and carries the same license. The Neovim integration follows the same approach. Teams redistributing fzf in a toolchain or desktop image need only preserve the copyright notice and license file.

The go.mod file lists six direct dependencies: fastwalk for file traversal, tcell/v2 for terminal rendering, go-shellwords for argument parsing, go-isatty for TTY detection, uniseg for Unicode segmentation, and the standard library extensions golang.org/x/sys and golang.org/x/term. The dependency list is intentionally minimal. Building fzf from source requires Go 1.23 or later as declared in go.mod.

Editorial conclusion

fzf suits developers who spend meaningful time in a terminal and want interactive selection over files, history, and process lists without writing custom menus. The shell integrations for Bash, Zsh, Fish, and Nushell are the fastest entry point; run brew install fzf and then follow the shell integration instructions in the README before investing time in custom workflows. The event-driven architecture is worth exploring only after the default integrations are in use, because the custom workflow features require familiarity with fzf's keybinding syntax and reload mechanics. Users on Windows should be aware that shell integration requires a compatible shell environment such as MSYS2 or WSL.

Frequently asked questions

What is fzf used for?

fzf is used to add interactive fuzzy selection to shell workflows. Common uses include fuzzy file search with CTRL-T, interactive command history search with CTRL-R, and directory navigation with ALT-C. It also integrates with Vim and Neovim for buffer and file selection.

How do I use fzf on Windows?

The README lists fzf for Windows via Chocolatey (choco install fzf), Scoop (scoop install fzf), Winget (winget install fzf), and MSYS2. Shell integration for key bindings and fuzzy completion requires a compatible shell environment such as MSYS2, Git Bash, or WSL.

How do I use fzf in a terminal?

After installing and setting up shell integration, fzf adds CTRL-T for file selection, CTRL-R for history search, and ALT-C for directory navigation. You can also pipe any command output directly into fzf and press Enter to select a line. The README documents the shell integration setup for Bash, Zsh, Fish, and Nushell.

How do I use fzf to find files?

With shell integration active, pressing CTRL-T while at a shell prompt opens fzf loaded with files and directories from the current location. Typing filters the list with fuzzy matching, and pressing Enter pastes the selected path into the command line. The FZF_DEFAULT_COMMAND environment variable controls the command used to generate the file list.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/junegunn-fzf.svg)](https://hysenlabs.com/projects/junegunn-fzf)
Community notes

Community notes