# What Is the Core Module of fff.nvim? Architecture and API Guide

> Understand the fff.nvim core module, lua/fff/core.lua. Discover its architecture and API to master this powerful fuzzy finder. Explore its orchestration layer for UI, matching, and file operations.

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

---

**The core module of fff.nvim is [`lua/fff/core.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/core.lua), which serves as the central orchestration layer that coordinates the fuzzy finder UI, matching engine, and file-system operations.**

The `fff.nvim` plugin by dmtrKovalenko is a high-performance fuzzy file finder for Neovim. At its heart lies the **core module**, a lightweight orchestrator that exposes the public API and manages the lifecycle of the picker interface while delegating heavy computation to specialized sub-modules.

## Location and Role of the Core Module

In the repository structure, the core module resides at **[`lua/fff/core.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/core.lua)**. Unlike monolithic plugins that bundle all logic in one file, fff.nvim follows a modular architecture where the core acts as the nexus. It maintains a singleton `state` table and wires together UI rendering from [`picker_ui.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/picker_ui.lua), fuzzy matching from [`fuzzy.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/fuzzy.lua), and external tool integration from the `utils/` directory.

## Key Responsibilities

The core module handles five critical areas of functionality:

### Public API Entry Points

The module exports three primary functions that users interact with: **`setup()`**, **`open()`**, and **`close()`**. These functions power the `:Fff` command and are accessible via the standard `require('fff')` interface. When you call `require('fff').setup()`, you are invoking the configuration merger in the core that validates options against defaults from [`lua/fff/conf.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/conf.lua).

### State Management

A singleton **`state`** table tracks the current candidate list, active selection index, preview buffer handles, and merged configuration options. The core initializes this state when `setup()` runs and updates it throughout the picker session. This centralized state ensures that UI components and the fuzzy matcher operate on consistent data without tight coupling.

### Event Loop and Callbacks

The core registers Neovim autocommands including **`BufLeave`**, **`BufEnter`**, and **`CursorMoved`** to manage picker lifecycle. It also maps keystrokes such as **`<CR>`** to accept selections and **`<C-c>`** to cancel. Rather than handling the logic directly, these callbacks delegate to the fuzzy matcher in [`lua/fff/fuzzy.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/fuzzy.lua) and the renderer in [`lua/fff/picker_ui.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/picker_ui.lua), keeping the core free of algorithmic complexity.

### Integration with Auxiliary Modules

The core calls file-system utilities from **[`lua/fff/utils/fs.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/utils/fs.lua)** and git helpers from **[`lua/fff/git_utils.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/git_utils.lua)** to generate candidate lists. It also conditionally loads the optional Rust performance backend from **[`lua/fff/rust/init.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/rust/init.lua)** when available, falling back to Lua implementations if the native module is absent.

### Health Check Integration

When users run **`:checkhealth fff`**, the core invokes **[`lua/fff/health.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/health.lua)** to verify that external dependencies like **ripgrep** and **fd** are installed and accessible in `$PATH`. This validation ensures the file listing backends required by the picker are functional before the UI opens.

## Practical Usage Examples

### Basic Setup

Configure the plugin by calling `setup()` in your [`init.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/init.lua):

```lua
require('fff').setup({
  prompt = 'Find file > ',
  preview = true,
  -- additional options merge with defaults from conf.lua
})

```

### Opening the Picker

Launch the fuzzy finder programmatically or via command:

```lua
-- Lua API
require('fff').open()

-- Vim command
vim.cmd('Fff')

```

### Accessing Core State Directly

For plugin development or advanced customization, access the core module internals:

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

-- Inspect current candidates
local items = core.state.items

-- Refresh the candidate list after configuration changes
core.refresh()

```

### Custom UI Integration

Replace the default picker UI while retaining core logic:

```lua
local fff = require('fff')
fff.setup({
  picker_ui = require('my_custom_ui'), -- must implement the expected interface
})

```

## Summary

- The **core module** of fff.nvim is located at [`lua/fff/core.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/core.lua) and functions as the central orchestrator.
- It exposes the **public API** (`setup`, `open`, `close`) and maintains a **singleton state** table for picker data.
- The core delegates heavy operations to **specialized sub-modules**: [`fuzzy.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/fuzzy.lua) for matching, [`picker_ui.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/picker_ui.lua) for rendering, and utility modules for file-system operations.
- It integrates with **Neovim's autocommand system** to handle buffer lifecycle and user input events.
- **Health checks** are triggered through the core to validate external binary dependencies.

## Frequently Asked Questions

### How do I access the internal state of the fff.nvim picker?

Import the core module directly using `local core = require('fff.core')` and inspect `core.state.items` for the current candidate list or `core.state.selected` for the active index. This is useful for building extensions that react to picker state changes.

### Can I use fff.nvim without the default UI?

Yes. Pass a custom `picker_ui` table to `require('fff').setup()` that implements the same interface as [`lua/fff/picker_ui.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/picker_ui.lua). The core module will call your custom render methods instead of the built-in UI, allowing full visual customization while keeping the fuzzy matching and file-system logic intact.

### What external dependencies does the core module check during health verification?

The core invokes [`lua/fff/health.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/health.lua) to verify that **ripgrep** and **fd** are installed and available in your system `$PATH`. These tools provide the high-performance file listing that feeds into the fuzzy matcher.

### Where does the core module store user configuration?

The core merges user-provided options with defaults defined in [`lua/fff/conf.lua`](https://github.com/dmtrKovalenko/fff.nvim/blob/main/lua/fff/conf.lua) into the `state.config` table. This merged configuration persists for the duration of the Neovim session and controls behavior such as preview window settings, prompt text, and keymap definitions.