HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
junegunn
fzf
Go2013–2026
junegunn / fzf

fzf

:cherry_blossom: A command-line fuzzy finder

210Distinct people
229Mentions
5Explicit recommenders
84.2KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

:cherry_blossom: A command-line fuzzy finder

GitHub

Where it is used

  • Canopy — Canopy uses fzf’s matching and scoring algorithm, hand-ported in shared/fuzzy.ts and compiled into its frontend bundle. This implements fuzzy matching inside the app. Source

What people are saying

`ripgrep` is my favorite of the "new" linux utilities Yeah, but only when used together with fzf, the other favorite new cross-platform shell utility. I mean, after rg spits…

stinos used a recommendation phrase. 5 indexed comments match. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 8–Nov 15 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/15/2026, 10:01:16 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year229 dated mentions

Observed mentions: 2013-11-05 12:23:55 UTC to 2026-10-19 23:55:18 UTC.

01020302013-01-01 00:00:00 UTC to 2014-01-01 00:00:00 UTC (exclusive): 2 mentions; 2 submissions, 0 comments20132014-01-01 00:00:00 UTC to 2015-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 15 mentions; 5 submissions, 10 comments2016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 10 mentions; 2 submissions, 8 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 22 mentions; 7 submissions, 15 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 23 mentions; 3 submissions, 20 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 22 mentions; 2 submissions, 20 comments20192020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 25 mentions; 1 submissions, 24 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 34 mentions; 2 submissions, 32 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 26 mentions; 1 submissions, 25 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 19 mentions; 0 submissions, 19 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 14 mentions; 2 submissions, 12 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 10 mentions; 2 submissions, 8 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 5 mentions; 0 submissions, 5 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20132013-01-01 00:00:00 UTC2014-01-01 00:00:00 UTC220
20142014-01-01 00:00:00 UTC2015-01-01 00:00:00 UTC202
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC15510
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC1028
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC22715
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC23320
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC22220
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC25124
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC34232
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC26125
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC19019
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC14212
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC1028
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC505

From the project README

An excerpt from the repository, fetched Nov 12, 2026.

Read the project’s introduction
Show your love for fzf -- T-shirts, mugs, and stickers now available! fzf is a general-purpose command-line fuzzy finder and an interactive terminal toolkit. Whether you're selecting files, browsing command history, previewing data, navigating complex datasets with fuzzy matching, or creating custom menus and workflows, fzf provides the building blocks to turn shell scripts into rich terminal applications. Highlights Portable // Distributed as a single binary for easy installation Fast // Optimized to process millions of items in milliseconds Programmable // Event-driven architecture for building custom terminal interfaces and workflows Batteries-included // Comes with integrations for Bash, Zsh, Fish, Nushell, Vim, and Neovim Table of Contents Installation Using Homebrew Using Mise Linux packages Windows packages Using git Binary releases Setting up shell integration Vim/Neovim plugin Upgrading fzf Building fzf Usage Using the finder Display modes --height mode --popup mode Search syntax Environment variables Customizing the look Options Demo Examples Key bindings for command-line Fuzzy completion Files and directories Process IDs Host names Environment variables / Aliases Customizing fuzzy completion for bash and zsh Customizing fzf options for completion Customizing completion source for paths and directories Supported commands (bash) Custom fuzzy completion Fuzzy completion for fish Fuzzy completion for Nushell Vim plugin Advanced topics Customizing for different types of input Performance Executing external programs Turning into a different process Reloading the candidate list 1. Update the list of processes by pressing CTRL-R 2. Switch between sources by pressing CTRL-D or CTRL-F 3. Interactive ripgrep integration Preview window Previewing an image Tips Respecting .gitignore Fish shell fzf Theme Playground Related projects License Goods Sponsors ❤️ Installation Using Homebrew You can use Homebrew (on macOS or Linux) to install fzf. brew install fzf ImportantTo set up shell integration (key bindings and fuzzy completion), see the instructions below. fzf is also available via MacPorts: sudo port install fzf Using Mise You can use mise to install fzf. mise use -g fzf@latest Linux packages Package Manager Linux Distribution Command APK Alpine Linux sudo apk add fzf APT Debian 9+/Ubuntu 19.10+ sudo apt install fzf Conda conda install -c conda-forge fzf DNF Fedora sudo dnf install fzf Nix NixOS, etc. nix-env -iA nixpkgs.fzf Pacman Arch Linux sudo pacman -S fzf pkg FreeBSD pkg install fzf pkgin NetBSD pkgin install fzf pkg_add OpenBSD pkg_add fzf Portage Gentoo emerge --ask app-shells/fzf Spack spack install fzf XBPS Void Linux sudo xbps-install -S fzf Zypper openSUSE sudo zypper install fzf ImportantTo set up shell integration (key bindings and fuzzy completion), see the instructions below. Windows packages On Windows, fzf is available via Chocolatey, Scoop, Winget, and MSYS2: Package manager Command Chocolatey choco install fzf Scoop scoop install fzf Winget winget install fzf MSYS2 (pacman) pacman -S $MINGW_PACKAGE_PREFIX-fzf Using git Alternatively, you can "git clone" this repository to any directory and run install script. git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf ~/.fzf/install The install script will add lines to your shell configuration file to modify $PATH and set up shell integration. Binary releases You can download the official fzf binaries from the releases page. https://github.com/junegunn/fzf/releases Setting up shell integration Add the following line to your shell configuration file. bash # Set up fzf key bindings and fuzzy completion eval "$(fzf --bash)" zsh # Set up fzf key bindings and fuzzy completion source <(fzf --zsh) fish # Set up fzf key bindings fzf --fish | source Nushell -- Nushell does not support piping into source, so the install script generates a file in the autoload directory. If you didn't use the install script, you can manually set it up: # Generate the integration script mkdir ($nu.default-config-dir | path join "autoload") fzf --nushell | save -f ($nu.default-config-dir | path join "autoload" "_fzf_integration.nu") Note--bash, --zsh, --fish, and --nushell options are only available in recent versions of fzf. If you have an older version of fzf, or want finer control, you can source individual script files in the /shell directory. The location of the files may vary depending on the package manager you use. Please refer to the package documentation for more information. (e.g. apt show fzf) TipYou can disable CTRL-T, CTRL-R, or ALT-C bindings by setting the corresponding *_COMMAND variable to an empty string when sourcing the script. For example, to disable CTRL-R and ALT-C: bash: FZF_CTRL_R_COMMAND= FZF_ALT_C_COMMAND= eval "$(fzf --bash)" zsh: FZF_CTRL_R_COMMAND= FZF_ALT_C_COMMAND= source <(fzf --zsh) fish: fzf --fish | FZF_CTRL_R_COMMAND= FZF_ALT_C_COMMAND= source nushell: add to your env.nu: $env.FZF_CTRL_R_COMMAND = ""; $env.FZF_ALT_C_COMMAND = "" Setting the variables after sourcing the script will have no effect. Vim/Neovim plugin If you use vim-plug, add this to your Vim configuration file: Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } Plug 'junegunn/fzf.vim' junegunn/fzf provides the basic library functions fzf#install() makes sure that you have the latest binary junegunn/fzf.vim is a separate project that provides a variety of useful commands To learn more about the Vim integration, see README-VIM.md. TipIf you use Neovim and prefer Lua-based plugins, check out fzf-lua. Upgrading fzf fzf is being actively developed, and you might want to upgrade it once in a while. Please follow the instruction below depending on the installation method used. git: cd ~/.fzf && git pull && ./install brew: brew update; brew upgrade fzf macports: sudo port upgrade fzf chocolatey: choco upgrade fzf vim-plug: :Plu
Read the full README on GitHub

What Hacker News says

19 sources
It's fast indeed. And I can't help keeping promoting the combination with fzf :) For those who want to try it out, this is a Powershell function but the same principle applies in any shell. Does ripgrep then puts fuzzy searching in the resulting files+text on top while showing context in bat: function frg { $result = rg --ignore-case --color=always --line-number --no-heading @Args | fzf --ansi ` --color 'hl:-1:underline,hl+:-1:underline:reverse' ` --delimiter ':' ` --preview "bat --color=always {1} --theme='Solarized (light)' --highlight-line {2}" ` --preview-window 'up,60%,border-bottom,+{2}+3/3,~3' if ($result) { & ($env:EDITOR).Trim("`"'") $result.Split(': ')[0] } } There are other ways to approach this, but for me this is a very fast way of nailing down 'I now someth
Read the rest
ing exists in this multi-repo project but don't know where exactly nor the exact name' edit this comes out of https://github.com/junegunn/fzf/blob/master/ADVANCED.md and even though you might not want to use most of what is in there, it's still worth glancing over it to get ideas of what you could do with it
In Ripgrep is faster than grep, ag, Git grep, ucg, pt, sift (2016)
Have you tried out using ripgrep [0] or fzf [1]? 200ms is quite a lot for history search, I'd expect search to be 20ms or less. In fact, it should be instantaneous as it should all fit in memory really. I've been using fzf and the searches are all faster than my monitor can display frames (so less than 16ms), although I only have 10k entries on my history as I clear it up once in a while. [0]: https://github.com/BurntSushi/ripgrep [1]: https://github.com/junegunn/fzf
In Cases where full scans are better than indexes
>Am I missing something? Yes, the article misses what fzf actually is by focusing too much on the shell integrations. I hardly ever use those features, except for fzf-tab (which partially subsumes them). Fundamentally, fzf is a well-behaved UNIX tool for choosing things. It does one thing well (choosing things), it communicates by simple text streams on stdin and stdout, and it integrates seamlessly with other text-based programs. It's like an interactive, human-friendly version of grep that narrows down the possibilities on every keypress. You pass any newline-separated text to its stdin, and it will let you choose from among them. Whatever you choose will get written to stdout. This can be a single choice or multiple choices. You can customize the layout and even run arbitrary scripts when each option is selected (not chosen) to show a
Read the rest
preview. Once you recognize it, "choosing things" shows up everywhere, so fzf can accelerate any terminal-based workflow. Examples of what I use it for: - what unit tests to run - what git branch/commit to check out - what process to kill - what wifi to connect to - what todo list items to check off - find an emoji and put it on the clipboard - you're leaving your laptop and you want to choose among shutdown/restart/suspend/logout/lockscreen - what files or options to pass into an arbitrary command (using fzf-tab) Basically anything that, if it were in a GUI, would be shown as radio buttons or checkboxes or a dropdown menu. You can use it in scripts/aliases, or you can just write a quick fzf command inline. I use it for so many things, it's hard to even recall them. It's part of my muscle memory now. Check the wiki on the fzf github, there are all kinds of examples. e.g. here's the one I use for killing processes[2]. An example from recently where I used it "inline": I was in the middle of debugging something in a Python project. I needed to temporarily remove a bunch of packages from the virtual envirnoment, but not all of them, to narrow down where the problem was coming from. After 20 seconds of trial and error (I forgot the syntax for tail) I had: pip uninstall $(pip list | tail -n+3 | cut -d' ' -f1 | fzf -m) This let me multi-select from the list of installed packages and uninstall them. Go down the list, boom-boom-boom, done. Pressing enter would uninstall my choices right away. Pressing tab would first expand the $() and replace it with the stdout of the pipeline inside, so the text after the prompt would become `pip uninstall requests numpy pandas ...` or whatever I chose, without running the `pip uninstall` part until I pressed enter. I tend to do the tab-expand trick a lot with multi-selections or with dangerous commands like rm, so I can double-check the full thing first before running it. NB: in that pip example, the "fuzzy" part wasn't even relevant. All I did was use the up- and down- arrows to navigate the list .. there were only a few dozen entries so I didn't need the fuzzy-search. In fact, in most of my scripts I actually turn off the fuzzy matching and use the --exact flag, so that it just searches for exact substrings, whitespace-separated, order ignored. I find this makes its behaviour more predictable. e.g. if I want to find a pyproject.toml file from among all my files, in --exact mode I can just type "pypro" and it will show like ~/repos/foo/pyproject.toml ~/repos/bar/pyproject.toml ~/old-stuff/scripts/pyproject.toml ... then I type "bar" to narrow it to the one in the "bar" repository, so my query is just "pypro bar". But unlike fuzzy mode, it doesn't show entries that just happen to have "b", "a", and "r" somewhere in the string, like something named ~/repos/big-archives/pyproject.toml ^ ^^ I have to type slightly more than I would with fuzzy-mode, but the lack of bad search results more than makes up for it. This is what I mean when I say the core of fzf is "choosing things". It's not really about fuzzy-searching, despite the name. [1] https://github.com/lincheney/fzf-tab-completion [2] https://github.com/junegunn/fzf/wiki/Examples#processes
In So you've installed `fzf` – now what?
This enables the C-r / M-c / C-t key bindings, but there's also a completion.bash file. This enables the "**" completion trigger, which can contextually complete paths, envvar names or PIDs in commands. (See "Fuzzy completion for bash and zsh" in fzf's readme [1]). Similarly, you can add to your .bashrc: if [ -e /usr/share/doc/fzf/examples/completion.bash ]; then source /usr/share/doc/fzf/examples/completion.bash fi /usr/share/doc/fzf/README.Debian explains this, as well as the setup for zsh, fish and vim. [1]: https://github.com/junegunn/fzf#fuzzy-completion-for-bash-an...
In So you've installed `fzf` – now what?
fzf is super useful for navigating and switching git branches I realised today [1] function gbll(){ local tags branches target branches=$( git --no-pager branch --sort=-committerdate \ --format="%(if)%(HEAD)%(then)%(else)%(if:equals=HEAD)%(refname:strip=3)%(then)%(else)%1B[0;34;1mbranch%09%1B[m%(refname:short)%(end)%(end)" \ | sed '/^$/d') || return tags=$( git --no-pager tag | awk '{print "\x1b[35;1mtag\x1b[m\t" $1}') || return target=$( (echo "$branches"; echo "$tags") | fzf --no-hscroll --no-multi -n 2 \ --ansi --preview="git --no-pager log -150 --pretty=format:%s '..{2}'") || return git checkout $(awk '{print $2}' <<<"$target" ) } [1]https://github.com/junegunn/fzf/wiki/Examples#git
In So you've installed `fzf` – now what?

Showing the 15 most recent of 19 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.