CLI tool
junegunn/fzf avatar
junegunn/fzf

fzf: The fuzzy finder that turns shell scripts into interactive terminal tools

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

84,188 stars3,434 forksGoMIT

At a glance

What is it?
fzf is a single-binary fuzzy finder for filtering files, history, and arbitrary text streams. It scales to millions of items and ships with shell and editor integrations, but its event-driven architecture is where the real power lies.
Who is it for?
Adopt fzf if you spend time in a terminal and want fast, scriptable fuzzy selection for files, history, or custom data streams. The single binary and MIT license make it low-risk to integrate.
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 2 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 November 13, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • junegunn/fzf84,188 ★ · +2,180
Star history
Repository2026-07-282026-11-13
junegunn/fzf82k84.2k

2,180 Stars in the last 108 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

What fzf actually solves

fzf solves a specific pain: choosing one item from a long list in a terminal without typing the full name. It reads text from stdin, displays it in an interactive list, and lets you filter with fuzzy matching. The README describes it as a general-purpose command-line fuzzy finder and an interactive terminal toolkit. That second phrase matters. fzf is not just a file picker. It is a building block for turning shell scripts into rich terminal applications. The target user is anyone who lives in a shell: developers, sysadmins, data analysts. The classic use cases are selecting files, browsing command history, and picking processes, but the design allows much more. The core value is speed and programmability. The README claims it is optimized to process millions of items in milliseconds. That is a bold claim, but the Go implementation and the single-binary distribution make it plausible. If you have ever waited for a recursive grep to finish before you could even start typing, fzf changes that workflow.

The mechanism: stdin in, selection out

fzf operates as a filter. You pipe text into it, it presents an interactive list, and when you select an item, it prints that item to stdout. The simplest invocation is something like `ls | fzf`. But the real power comes from the event-driven architecture. The README mentions this explicitly: fzf is programmable and event-driven. That means you can reload the candidate list on the fly, execute external programs, and change the entire process. For example, the README describes reloading the list of processes by pressing CTRL-R, switching between sources with CTRL-D or CTRL-F, and integrating interactive ripgrep. The data flow is not static. You can have fzf run a command, take its output as the new list, and keep the current query. This makes it a dynamic interface, not just a static picker. The preview window is another key mechanism. You can define a command that shows details for the currently highlighted item. The README gives examples like previewing an image. That turns fzf into a lightweight file manager or data browser.

Getting it running: installation and shell integration

Installation is straightforward because fzf is distributed as a single binary. The README lists package managers for every major platform. On macOS or Linux, `brew install fzf` works. On Debian or Ubuntu, `sudo apt install fzf`. On Windows, you have Chocolatey, Scoop, Winget, and MSYS2. There is also a git-based install and binary releases. The important step after installation is shell integration. The README has a section titled Setting up shell integration, and it warns that key bindings and fuzzy completion require this step. The README lists integrations for Bash, Zsh, Fish, and Nushell. The warning is clear: without this step, you get the bare finder but not the key bindings or fuzzy completion. For Vim and Neovim, there is a plugin. The README mentions it as part of the batteries-included philosophy. So the first run is not just `fzf`; you need to configure your shell to get the full experience.

Search syntax and customization

The search syntax is one of fzf's strengths. It supports fuzzy matching by default, but you can use exact matches, prefix matches, and suffix matches. The README has a section on search syntax. You can customize the look and behavior extensively. There are options for display modes: `--height` mode and `--popup` mode. The `--height` mode keeps fzf within a certain number of lines, so it does not take over the whole terminal. The `--popup` mode makes it appear as a popup, which is useful in editors. Environment variables are also part of the configuration. The README lists them under Environment variables. This means you can set defaults in your shell profile rather than passing flags every time. The customization goes deep. The README mentions a Theme Playground and tips for respecting `.gitignore`. The latter is important: you can make fzf respect your project's ignore rules, which is a common need when searching files.

A real limitation: it is interactive by design

fzf is not a replacement for non-interactive filtering. If you need to filter a stream in a script without human input, fzf is the wrong tool. It waits for a selection. Another limitation is the preview window. It depends on external commands and your terminal emulator. Image previews, for example, require a compatible terminal and additional setup. The README has a section on previewing an image, which implies it is not a plug-and-play feature. Also, the event-driven architecture has a learning curve. The README's advanced topics cover reloading and executing external programs, but that is not beginner material. You need to understand shell scripting and how fzf's events work. Finally, the project moves fast. The release history shows v0.74.3 (August 2026), v0.74.4 (September 2026) and v0.74.5 (October 2026). That means options and behaviors can change. If you rely on a specific flag, you need to watch the changelog.

Alternatives: peco and skim take different paths

fzf is not the only fuzzy finder. Two notable alternatives are peco and skim. peco is written in Go and follows a simpler model. It reads stdin, filters, and prints the selection. skim is written in Rust and aims for high performance, similar to fzf's claim. The key difference in approach is that fzf emphasizes programmability and shell integration. The README highlights this with the event-driven architecture and the integrations for Bash, Zsh, Fish, Nushell, Vim, and Neovim. If you want a drop-in tool that works with your editor and shell out of the box, fzf's listed integrations are the draw.

Maintenance and license

fzf is actively maintained. The last push was 2 November 2026, and releases come out regularly. The project is not archived. The license is MIT, which is permissive. You can use it in commercial projects, modify it, and redistribute it, as long as you include the copyright notice. This is a low barrier for adoption. The README also mentions sponsorship and merchandise, which suggests a sustainable project. The single-binary distribution means upgrading is simple: replace the binary. The README has a section on upgrading fzf. For shell integration, you need to keep the scripts in sync with the binary. If you install via a package manager, that is handled for you. If you install from git, you need to pull and re-run the install script. The release cadence is fast, which is good for bug fixes but can be a maintenance burden if you pin a specific version. You should check the release notes before upgrading, especially for breaking changes in options or key bindings.

Editorial conclusion

Adopt fzf if you spend time in a terminal and want fast, scriptable fuzzy selection for files, history, or custom data streams. The single binary and MIT license make it low-risk to integrate. Skip it if you need a GUI or if your workflow demands deterministic, non-interactive filtering; for that, use grep or ripgrep directly. Before adopting, verify that the shell integration scripts for your shell (Bash, Zsh, Fish, Nushell) match your environment, and test the preview window with your terminal emulator, since image previews require extra setup. Also check the latest release notes for any breaking changes in options or key bindings, as the project evolves quickly with frequent releases.

Frequently asked questions

What is fzf used for?

fzf is a general-purpose command-line fuzzy finder and interactive terminal toolkit. It filters files, command history, processes and other text streams, and its shell integration adds key bindings and fuzzy completion to your prompt.

How do I use fzf on Windows?

fzf is packaged for Windows through Chocolatey, Scoop, Winget and MSYS2. The repository also ships an install.ps1 script alongside the shell install script.

How do I use fzf to find files?

You pipe a list of paths into fzf and it filters them as you type, selecting the closest match. The go.mod depends on fastwalk for fast directory traversal, and an advanced topic covers respecting .gitignore when walking a tree.

How to use fzf in terminal?

Install it with a package manager, then follow the README's "Setting up shell integration" section so the shell key bindings and fuzzy completion are configured. The package manager alone gives you the binary without the bindings.

what is junegunn fzf

It is a Go implementation of a fuzzy finder, MIT licensed and distributed as a single binary for Linux, macOS, Windows, FreeBSD, NetBSD, OpenBSD and NixOS. The default branch is master and the newest release is 0.74.5.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
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)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/junegunn-fzf.svg)](https://hysenlabs.com/projects/junegunn-fzf)

Was this useful?