A search engine for the second query, not the first
FFF makes a focused argument: command-line search tools are excellent when a person runs one query, but repeated process startup and filesystem walking become wasteful inside an editor or AI agent. FFF scans once, keeps an index warm, watches for changes, and answers later searches from the same process. That gives it room to retain Git status, file metadata, content, query history, and frecency, meaning how recently and frequently a file was used.
This distinction matters more than the project's speed charts. A terminal user who searches, reads the answer, and exits gains little from a resident service. An agent that performs dozens of related searches can avoid rebuilding the same view of a repository. The README is admirably direct about the boundary: ripgrep remains the right tool for one grep, while FFF is designed for long-running repeated-search workloads.
FFF is not merely a Neovim picker anymore. The same Rust core appears as a native crate, a stable C interface, Node and Bun packages, Python bindings, a Pi agent extension, and an MCP server. That shared engine is the product. It lets an editor and an agent receive similar ranked, structured results without scraping terminal output.
Search results carry useful context
Path search is typo tolerant and ranks files using both matching and frecency. Content search supports literal, regular-expression, and fuzzy modes, with smart case and an automatic fuzzy fallback when an exact query finds nothing. Multi-pattern search can look for several identifiers in one pass. Results can include line and column positions, context, definition-like classification, file metadata, and Git state.
For an agent, structured pagination is particularly valuable. A tool can request the next page rather than dumping an unbounded grep result into model context. Definition-first hints can surface declarations before incidental uses, while annotations for modified, staged, and untracked files point the model toward current work. The MCP server exposes ffgrep, fffind, and multi-pattern search to Claude Code, Codex, OpenCode, Cursor, Cline, and other compatible clients.
Neovim gets the most complete human interface. The picker supports file, directory, and mixed searches, previews, live grep, multi-select, quickfix output, Git highlighting, custom layouts, and query constraints such as extensions or excluded directories. It also provides health checks and session logs, which matter because a native module and background index are harder to diagnose than a Lua-only filter.
Installation is easy until integration begins
The MCP binary has a one-line installer for Unix-like systems, a PowerShell route for Windows, and a Homebrew formula. The scripts are in the repository for inspection. Codex users are told to register an absolute binary path because desktop sessions may not inherit the interactive shell path. The Neovim plugin downloads a prebuilt library and falls back to a Cargo build. Node and Python users install normal packages.
Using the SDK correctly takes more thought. A caller creates a finder for a base path, waits for its initial scan, queries it repeatedly, and destroys it when finished. Switching roots can block while a new index is installed. Filesystem watching, content indexing, memory-mapped caching, frecency databases, and scan timeouts are application decisions, not invisible implementation details. C users must call the library's matching free functions rather than the standard allocator.
MCP currently has a notable root limitation. An open report says the server does not act on roots/list_changed, so a directory added later through Claude Code's /add-dir remains unindexed. The command accepts one startup path, which leaves multi-root sessions without a clean workaround. If your workspaces are dynamic, test that workflow before making FFF the agent's preferred search tool.
The speed is purchased with memory
FFF's warm queries avoid repeated filesystem traversal and process startup. The project reports sub-10 millisecond queries on a 500,000-file Chromium checkout after indexing, compared with seconds for fresh ripgrep processes. Those are project measurements, so hardware, filesystem cache, ignore rules, and query shape can change the result. The architectural advantage for repeated calls is still credible even if your numbers differ.
The trade is resident memory. The README estimates about 360 bytes for each content-indexed file, around 36 MB for 100,000 eligible files. It reports roughly 26 MB resident for a 14,000-file repository and says a Chromium-sized tree can require a few hundred megabytes. Binaries and oversized files are excluded, and a memory-mapped option can reduce anonymous memory pressure, but the index never becomes free. Containers and many concurrent workspaces need explicit budgets.
The background watcher is another part of the price. It keeps results current without rescanning on every query, yet watcher behavior varies by platform and repository shape. Recent release work reduced rescans in very large home directories and fixed empty-directory and ignore compatibility cases. An open, detailed report also argues that high-volume changes inside ignored build directories can trigger unnecessary full rescans or stale indexes. Performance testing should include your real build process, not only an idle checkout.
Correct scope matters more than a fast answer
Two current bugs deserve special attention for agent use. One report reproduces MCP multi-pattern search ignoring a standalone positive directory or exact-file constraint. Another reproduces Node AI-mode regular-expression search returning a match outside an exact-file constraint. Both produce successful-looking results rather than an explicit error. An agent can therefore read irrelevant code, waste context, or make a decision based on a scope it believes was enforced.
These are not reasons to dismiss the whole engine, but they change responsible adoption. Build small fixtures that assert include paths, excluded paths, exact files, regex alternation, ignore behavior, and multiple patterns. Keep ripgrep available as a fallback for sensitive checks. Search correctness is part of safety when downstream tools can edit files or execute commands.
Neovim users have a different operational risk. An open report traces a native crash to exhausted LMDB reader slots after several long-running sessions. Another reports a crash when Neovim starts from a directory deleted by a different shell. Native speed comes with native failure modes, so the documented health command, logs, and crash-debug instructions are useful rather than decorative.
An active project worth adopting deliberately
FFF was pushed and released on August 7, 2026. Version 0.10.3 shipped packages across its supported languages and included fixes for ignore handling, auxiliary finder reuse, giant home-directory scans, packaging, and security advisories in a dependency. New issues and pull requests were active on August 8. The repository's open count combines both, so 68 is an active work queue, not a count of confirmed bugs.
The documentation is excellent for a project this young. It explains where FFF wins, where ripgrep wins, how memory scales, how each binding manages lifecycle, and how the query language behaves. Use FFF when repeated search latency and enriched results are important enough to justify a resident index. Keep simpler tools for one-off work, and validate scoped queries before trusting them inside an autonomous agent.