# How to Set Up File Fuzzy Finding with fzf-lua in Neovim: A Complete Guide

> Master file fuzzy finding in Neovim with fzf-lua. This guide shows how to set up this powerful tool with Git icons and intuitive keymaps for efficient coding.

- Repository: [jdhao/nvim-config](https://github.com/jdhao/nvim-config)
- Tags: how-to-guide
- Published: 2026-03-04

---

**The jdhao/nvim-config repository provides a production-ready fzf-lua integration that lazy-loads on the `VeryLazy` event, configures a centered floating window with Git icons, and binds intuitive `<leader>` keymaps for files, live grep, buffers, and help tags.**

This guide walks through the exact implementation used in jdhao/nvim-config to enable blazing-fast file fuzzy finding. The setup leverages **ibhagwan/fzf-lua**, a Lua-based wrapper around the native fzf binary, and organizes the configuration across modular Lua files for optimal startup performance and maintainability.

## Plugin Declaration and Lazy Loading

The first step registers fzf-lua as a managed plugin while ensuring it does not impact Neovim's startup time. In [`lua/plugin_specs.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/plugin_specs.lua) at lines 122–127, the plugin is declared with the `VeryLazy` event trigger:

```lua
{
  "ibhagwan/fzf-lua",
  event = "VeryLazy",
  config = function()
    require("config.fzf-lua")
  end,
}

```

This declaration instructs the plugin manager to download **ibhagwan/fzf-lua** from GitHub and defer its initialization until the `VeryLazy` event fires—after the UI has fully loaded. The `config` callback points to the dedicated configuration module at [`lua/config/fzf-lua.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/config/fzf-lua.lua), keeping the plugin specification clean and the setup logic isolated.

## Configuring the fzf-lua Interface

The core configuration resides in [`lua/config/fzf-lua.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/config/fzf-lua.lua) (lines 1–41), where the `setup()` function merges custom options with the plugin defaults. The jdhao/nvim-config implementation prioritizes a minimal, centered interface:

- **Window layout**: A floating window positioned at `row = 0.5` and `height = 0.7`, creating a centered dialog occupying 70% of the screen height
- **Preview**: Disabled by default (`previewers = { builtin = { enable = false } }`) to maintain snappy performance
- **Icons**: Mini file icons and Git integration enabled for visual scanning
- **Respect .gitignore**: The file picker automatically excludes entries listed in `.gitignore`, with the option to override via `.rgignore` for fine-grained control

The configuration calls `require("fzf-lua").setup({...})` with these parameters, establishing the baseline behavior for all subsequent picker invocations.

## Essential Keymaps for Fuzzy Finding

After initialization, the configuration registers a suite of normal-mode mappings under the `<leader>` prefix. These mappings trigger specific `FzfLua` commands without requiring manual typing:

- **`<leader>ff`**: Search files in the current project (respects `.gitignore`)
- **`<leader>fg`**: Live grep across the codebase using ripgrep
- **`<leader>fh`**: Search Neovim help tags
- **`<leader>fb`**: List and switch between open buffers
- **`<leader>fr`**: Access recently opened files

Each mapping uses `vim.keymap.set` with the `noremap` and `silent` flags to ensure clean execution. The `<leader>` key defaults to backslash (`\`) unless redefined elsewhere in the configuration (commonly mapped to space in [`lua/mappings.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/mappings.lua)).

## Prerequisites and External Dependencies

While the Lua configuration handles the UI and keybindings, the actual fuzzy-finding logic depends on external binaries that must be installed separately:

1. **fzf**: The core fuzzy finder binary
   ```bash
   # macOS

   brew install fzf
   
   # Ubuntu/Debian

   sudo apt install fzf
   ```

2. **ripgrep** (optional but recommended): Powers the `live_grep` functionality for fast, recursive regex search
   ```bash
   brew install ripgrep
   # or

   sudo apt install ripgrep
   ```

The plugin detects these binaries at runtime. If `ripgrep` is missing, the `live_grep` feature will fail gracefully or fall back to alternative search methods depending on your fzf-lua version.

## Usage Examples and Lua API

Beyond the keymaps, you can invoke fzf-lua programmatically via the command line or Lua scripts. The following examples demonstrate both interfaces:

**Command-line usage:**

```vim
" Find files (respecting .gitignore)
:FzfLua files

" Search text across the project
:FzfLua live_grep

" Browse help documentation
:FzfLua helptags

" Switch between open buffers
:FzfLua buffers

```

**Lua API for custom scripts:**

```lua
local fzf = require('fzf-lua')

-- Open file picker with current configuration
fzf.files()

-- Live grep with specific options
fzf.live_grep()

-- Search old files (recently opened)
fzf.oldfiles()

```

The Lua API accepts optional tables to override the defaults set during initialization, allowing contextual behavior for specialized workflows.

## Summary

- The jdhao/nvim-config setup splits fzf-lua configuration between [`lua/plugin_specs.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/plugin_specs.lua) (plugin registration) and [`lua/config/fzf-lua.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/config/fzf-lua.lua) (behavior and keymaps)
- **Lazy loading** on the `VeryLazy` event ensures zero startup time impact
- The interface uses a **centered floating window** at 70% height with Git icons enabled and previews disabled for speed
- Keymaps follow the `<leader>f` convention: `ff` for files, `fg` for grep, `fh` for help, `fb` for buffers, `fr` for recent files
- You must install the **fzf binary** and optionally **ripgrep** system-wide for full functionality

## Frequently Asked Questions

### Do I need to install fzf separately from the Neovim plugin?

Yes. The **ibhagwan/fzf-lua** plugin is a Lua interface that communicates with the native `fzf` binary. You must install fzf via your system package manager (e.g., `brew install fzf` or `sudo apt install fzf`) before the fuzzy finder will function. The plugin does not bundle the binary.

### How do I change the window size or enable file previews?

Modify the `setup()` call in [`lua/config/fzf-lua.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/config/fzf-lua.lua). To adjust the window dimensions, change the `row`, `col`, `width`, or `height` values in the `winopts` table. To enable previews, remove or set to `true` the `enable = false` flag inside the `previewers.builtin` configuration.

### Can I use fzf-lua without ripgrep?

Yes, but with limited functionality. The **files** picker works independently of ripgrep, relying instead on the `fzf` binary and `find` or `fd` (if installed). However, the **live_grep** feature (`<leader>fg`) specifically requires ripgrep (`rg`) to perform real-time text searching across the codebase.

### What is the VeryLazy event and why is it used?

`VeryLazy` is a lifecycle event provided by modern Neovim plugin managers (like lazy.nvim) that fires after the UI and all initial buffers have loaded. By specifying `event = "VeryLazy"` in [`lua/plugin_specs.lua`](https://github.com/jdhao/nvim-config/blob/main/lua/plugin_specs.lua), the configuration ensures fzf-lua loads only when first needed—typically when you press a mapped key—keeping your Neovim startup time minimal and responsive.