# fff.nvim Example Usage: Complete Guide to Fast File Finding in Neovim

> Master fff.nvim for lightning-fast file finding in Neovim. Explore example usage, configuration, and search modes to boost your coding workflow. Get the complete guide now.

- Repository: [Dmitriy Kovalenko/fff.nvim](https://github.com/dmtrKovalenko/fff.nvim)
- Tags: tutorial
- Published: 2026-04-04

---

**To use fff.nvim, install the plugin with a Rust binary build, then call `require('fff').find_files()` or `require('fff').live_grep()` with optional configuration overrides for layout, search modes, and filters.**

**fff.nvim** is a high-performance file finder and live grep plugin for Neovim that combines a Lua-based UI with a Rust-powered search engine. This guide provides practical **fff.nvim example usage** patterns drawn directly from the source code, demonstrating how to configure the plugin, invoke searches, and integrate advanced features like frecency scoring and Git status tracking.

## Minimal Installation with lazy.nvim

The plugin requires a Rust binary that handles filesystem indexing and search operations. When using `lazy.nvim`, define a build step to handle the compilation or download automatically.

```lua
{
  'dmtrKovalenko/fff.nvim',
  build = function()
    -- Downloads a pre‑built binary or builds it from source
    require('fff.download').download_or_build_binary()
  end,
  opts = {
    debug = {
      enabled = true,            -- show file‑info panel
      show_scores = true,        -- display scoring data in the UI
    },
  },
  keys = {
    { 'ff', function() require('fff').find_files() end,   desc = 'Find files' },
    { 'fg', function() require('fff').live_grep() end,    desc = 'Live grep' },
    { 'fc', function() require('fff').live_grep({ query = vim.fn.expand('<cword>') }) end,
      desc = 'Grep word under cursor' },
  },
}

```

*Source*: [`lua/fff/main.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/main.lua) (entry points `find_files` and `live_grep`) and [`lua/fff/picker_ui.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/picker_ui.lua) (window rendering).

## Core API Functions

The public API exposed in [`lua/fff/main.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/main.lua) provides three primary entry points for file and content discovery.

### Finding Files

Call `find_files()` to open a fuzzy finder over your project directory. Pass an options table to customize the title, result limits, or layout for that specific invocation.

```lua
local fff = require('fff')

-- Open the picker with a custom title and reduced result set
fff.find_files({
  title = 'My Project Files',
  max_results = 50,
})

```

This delegates to `picker_ui.open()` in [`lua/fff/picker_ui.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/picker_ui.lua), which spawns the Rust-based `FilePicker::new_with_shared_state` in a background thread.

### Live Grep

Use `live_grep()` to search file contents with bigram-accelerated indexing. Configure search modes, case sensitivity, and preview positioning per call.

```lua
-- Perform a grep limited to specific modes with bottom preview
fff.live_grep({
  grep = { modes = { 'plain' } },
  query = 'TODO',
  layout = { preview_position = 'bottom' },
})

```

The search engine in [`crates/fff-grep/src/lib.rs`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/crates/fff-grep/src/lib.rs) handles the query parsing and content scanning, supporting plain text, regex, and fuzzy matching modes.

## Configuration Examples

Configuration is managed through `require('fff').setup()` or the global `vim.g.fff` table, defined in [`lua/fff/conf.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/conf.lua).

### Layout and Preview

Control floating window geometry and preview behavior via the `layout` and `preview` sections.

```lua
require('fff').setup({
  layout = {
    height = 0.8,
    width = 0.9,
    preview_position = 'right',
    preview_size = 0.5,
  },
  preview = {
    enabled = true,
    max_size = 100000,       -- bytes
    binary_file_threshold = 1024,
    line_numbers = true,
  },
})

```

### Frecency and History

Enable frecency tracking to bias results toward recently and frequently opened files. History remembers previous queries and boosts repeated selections.

```lua
{
  frecency = {
    enabled = true,
    db_path = vim.fn.stdpath('data') .. '/fff/frecency.db',
  },
  history = {
    enabled = true,
    db_path = vim.fn.stdpath('data') .. '/fff/history.db',
    min_combo_count = 3,
    combo_boost_score_multiplier = 1.5,
  },
}

```

These features are implemented in [`crates/fff-core/src/frecency.rs`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/crates/fff-core/src/frecency.rs) and integrate with the `FilePicker` index.

## Advanced Usage Patterns

Beyond basic file finding, **fff.nvim example usage** includes programmatic searches, manual index management, and debugging utilities.

### Programmatic Search

Access the Rust search engine directly without opening the UI by calling `search()` with a query string and result limit. This returns a Lua table of matches for custom processing.

```lua
local fff = require('fff')
local results = fff.search('init', 20)   -- returns up to 20 matches

for _, file in ipairs(results) do
  print(file.relative_path, file.frecency_score)
end

```

*Source*: [`lua/fff/main.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/main.lua) → `M.search` → `FilePicker::fuzzy_search_files`.

### Manual Index Management

Force a full filesystem rescan after massive repository changes like branch switches or bulk file operations.

```lua
-- Trigger a complete rescan in the background
require('fff').scan_files()

```

Refresh Git status caching independently of the file scan:

```lua
require('fff').refresh_git_status()

```

Both functions delegate to `FilePicker` methods in [`crates/fff-core/src/file_picker.rs`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/crates/fff-core/src/file_picker.rs).

### Runtime Debugging

Toggle debug mode and scoring overlays without restarting Neovim:

```lua
-- Enable score visualization in the picker
vim.api.nvim_command('FFFDebug on')

```

This updates the configuration defined in [`lua/fff/conf.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/conf.lua) at runtime.

## Summary

- **fff.nvim** separates the Lua UI ([`lua/fff/picker_ui.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/picker_ui.lua)) from the Rust search core (`crates/fff-core/`) for non-blocking performance.
- Install via package managers using `require('fff.download').download_or_build_binary()` to handle the Rust binary compilation.
- Invoke `find_files()` and `live_grep()` from [`lua/fff/main.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/main.lua) with per-call option overrides for layout and search modes.
- Configure persistence via `setup()` in [`lua/fff/conf.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/conf.lua), supporting frecency scoring, history, and Git status integration.
- Use `scan_files()` and `refresh_git_status()` to manually synchronize the index after large repository changes.
- Access the search engine programmatically via `search()` for custom tooling and AI agent integrations.

## Frequently Asked Questions

### How do I install fff.nvim if I don't have Rust installed?

The plugin includes a download mechanism that retrieves pre-built binaries for supported platforms. In your package manager configuration, ensure you call `require('fff.download').download_or_build_binary()` in the build step. If a pre-built binary is unavailable for your system, you will need Rust to compile from source.

### Can I use fff.nvim without opening the floating window?

Yes. The `search()` function in [`lua/fff/main.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/main.lua) provides direct access to the Rust fuzzy search engine. Pass a query string and maximum results count to receive a Lua table of matches containing file paths and frecency scores, enabling integration with scripts or other plugins.

### What is the difference between `find_files` and `live_grep` in fff.nvim?

`find_files()` searches filenames using a fuzzy matching algorithm against the filesystem index built by `FilePicker::fuzzy_search`. `live_grep()` searches file contents using a bigram index built by `build_bigram_index` in Rust, supporting plain text, regex, and fuzzy content matching with real-time results as you type.

### How do I force a rescan of my project directory?

Call `require('fff').scan_files()` to trigger `FilePicker::scan_files` in the Rust backend. This walks the filesystem using `ignore::WalkBuilder`, rebuilds the file index, and updates the bigram overlay. Use this after operations that modify many files at once, such as checking out a different Git branch.