What is fff.nvim Main Entry Point? Complete Plugin Architecture Guide
The fff.nvim main entry point is plugin/fff.lua, which Neovim automatically executes on startup to register commands and defer initialization, while the public API resides in lua/fff.lua (re-exporting fff.main) where users access functions like find_files() and live_grep().
Understanding the entry point architecture of dmtrKovalenko/fff.nvim is essential for configuring and debugging this fast fuzzy finder. The plugin employs a two-stage initialization system that separates Neovim's startup sequence from the heavy lifting performed by its Rust-powered indexing backend.
The Two-Stage Entry Point Architecture
fff.nvim splits its initialization across conventional Neovim runtime paths to optimize startup performance. This design ensures that expensive operations—such as building the fuzzy search index—run only when absolutely necessary.
Stage 1: The Plugin Entry Point (plugin/fff.lua)
Neovim automatically sources all files in plugin/ directories during startup, making plugin/fff.lua the true fff.nvim main entry point. According to the source code, this file performs three critical tasks:
- Registers public user commands including
:FFFFindand:FFFScan - Defers heavy indexing work until after the UI is ready
- Triggers
require('fff.core').ensure_initialized()the first time a picker is invoked
This lazy initialization strategy prevents Neovim's startup time from being affected by the Rust backend compilation or file system scanning.
Stage 2: The Public API Module (lua/fff.lua)
When users call require('fff') in their configuration, they access lua/fff.lua. This file acts as a thin proxy that immediately re-exports the implementation:
-- lua/fff.lua
return require('fff.main')
The actual API implementation lives in lua/fff/main.lua, which contains the core functionality for setup(), find_files(), and live_grep().
How fff.nvim Initializes on Startup
The complete startup flow demonstrates the separation of concerns between the entry point and the core engine:
Neovim startup → loads plugin/fff.lua → sets up lazy init & commands
→ when a command or require('fff') is used,
lua/fff.lua → lua/fff/main.lua (core functionality)
By deferring require('fff.core').ensure_initialized() until the first picker invocation, the plugin maintains minimal impact on editor launch times while keeping the fuzzy finder immediately accessible via command mappings.
Practical Usage Examples
Installing with lazy.nvim
Even when using a plugin manager, the fff.nvim main entry point handles its own lazy loading internally:
-- Lazy-load with lazy.nvim (the plugin still self-initializes)
{
'dmtrKovalenko/fff.nvim',
lazy = false, -- the plugin handles its own lazy loading
opts = { -- optional configuration passed to `require('fff').setup`
lazy_sync = true,
debug = { enabled = true, show_scores = true },
},
}
Accessing the Public API
After the entry point has run, access the main functions through the public module:
-- Directly require the public module
local fff = require('fff') -- this loads lua/fff.lua → lua/fff/main.lua
-- Open the file picker
fff.find_files()
-- Perform a live grep
fff.live_grep({ query = 'TODO' })
Triggering Initialization Manually
In rare cases where you need the core ready before UI interaction:
-- If you need the core to be ready before any picker interaction
require('fff.core').ensure_initialized()
Core Files in the Entry Point Chain
Understanding these source files clarifies the data flow from Neovim startup to fuzzy search execution:
plugin/fff.lua– The Neovim plugin entry point that registers commands and defers indexinglua/fff.lua– Public module that users import withrequire('fff'), forwarding tofff.mainlua/fff/main.lua– Core API implementation containingsetup(),find_files(), andlive_grep()lua/fff/core.lua– Initialization logic that ensures the Rust backend is readycrates/fff-core/src/lib.rs– Rust backend performing the fast fuzzy search and indexing
Summary
- fff.nvim main entry point is
plugin/fff.lua, automatically sourced by Neovim on startup - The plugin defers heavy initialization until first use via
require('fff.core').ensure_initialized() - Public API access flows through
lua/fff.lua→lua/fff/main.luawhen callingrequire('fff') - Commands like
:FFFFindare registered immediately, but the Rust backend initializes lazily - Users configure the plugin through
require('fff').setup()in their initialization files
Frequently Asked Questions
What file does Neovim load first when starting fff.nvim?
Neovim automatically loads plugin/fff.lua first because it resides in the plugin/ directory, which the runtime scans during startup. This file registers the user commands and sets up the lazy initialization hooks before any user configuration runs.
Why does fff.nvim use a two-stage entry point?
The two-stage architecture separates command registration (which must happen immediately) from resource-intensive indexing operations. By placing the heavy Rust backend initialization in fff.core and deferring it until first use, the plugin prevents Neovim's startup time from increasing while keeping the fuzzy finder instantly accessible via :FFFFind or :FFFScan.
How do I access the main fff.nvim functions in my configuration?
Import the public module with local fff = require('fff'), which returns the API defined in lua/fff/main.lua. This gives you access to fff.find_files(), fff.live_grep(), and fff.setup() for configuration. You do not need to manually require the entry point file; simply requiring 'fff' loads the full API after the initial plugin setup has occurred.
When is the Rust backend actually initialized?
The Rust backend initializes only when require('fff.core').ensure_initialized() is called, which happens automatically the first time you invoke a picker through :FFFFind, :FFFScan, or the Lua API functions. This lazy loading ensures that the computational cost of indexing your file system occurs after Neovim's UI is fully rendered and responsive.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →