How to Update fff.nvim: Complete Guide for Plugin Users and Maintainers

Update fff.nvim automatically via your plugin manager's build hook, manually using Lua API commands like ensure_downloaded(), or by building from source with build_binary().

The fff.nvim plugin is a fuzzy finder for Neovim that relies on a companion Rust binary for high-performance file searching. Because the plugin architecture spans both Lua and Rust, the update process involves synchronizing the Lua plugin code with the correct native binary version for your platform. This guide covers the three contexts for updating: automatic updates via plugin managers, manual command-line updates, and the release workflow for project maintainers.

Updating via Plugin Manager (Lazy.nvim)

Most users manage fff.nvim through a plugin manager like lazy.nvim, which automates the binary synchronization through a build hook. According to the source code in lua/fff/download.lua, the download_or_build_binary() function orchestrates the entire process.

When you update the plugin through your package manager, the build hook executes before the plugin becomes available:

{
  'dmtrKovalenko/fff.nvim',
  build = function()
    -- Downloads the pre‑built binary or falls back to a local cargo build
    require('fff.download').download_or_build_binary()
  end,
  opts = { debug = { enabled = true, show_scores = true } },
  lazy = false,
  keys = {
    { "ff", function() require('fff').find_files() end, desc = 'FFFind files' },
    { "fg", function() require('fff').live_grep()   end, desc = 'LiFFFe grep' },
  },
}

The build hook triggers the following sequence:

  1. Tag Resolution – The plugin reads the current version from lua/fff/utils/version.lua to determine the correct GitHub release tag (handling both stable releases and nightly/dev builds).
  2. Download Attempt – It calls download_from_github (lines 83-122 in download.lua) to fetch the pre-built binary for your specific platform triple (e.g., x86_64-unknown-linux-gnu).
  3. Fallback Build – If no pre-built asset exists or the download fails, the function automatically triggers build_binary() (lines 215-232), which runs cargo build --release in the repository root.

This entire process completes during the lazy-loading phase, ensuring the binary is ready before you invoke any picker commands.

Manual Update Methods

You can force an update or build from source without waiting for a plugin manager sync by executing Lua functions directly in Neovim.

Force a Fresh Binary Download

To bypass the cache and re-download the current release version, use ensure_downloaded with the force flag:

:lua require('fff.download').ensure_downloaded({force = true}, function(ok, err) 
  print(ok and 'fff.nvim binary refreshed' or 'Failed: ' .. err) 
end)

This corresponds to line 35 in lua/fff/download.lua, where download_or_build_binary() internally calls ensure_downloaded({force = true}).

Build from Source

If you have Rust installed and want to compile the binary locally (useful for development or unsupported platforms), run:

:lua require('fff.download').build_binary(function(ok, err) 
  if ok then
    print("Successfully built fff.nvim binary")
  else
    print("Build error: " .. err)
  end
end)

Verify Binary Location

To confirm which binary is currently active or debug path issues:

:lua print(require('fff.download').get_binary_path())

Release Author Workflow

If you are maintaining a fork or contributing releases, use the automated release script at scripts/release.sh to publish new versions. This script handles version bumping, Git tagging, and CI triggering.

The release process executes three critical steps:

  1. Version Bump – Runs cargo set-version <new_version> (using cargo-edit, which the script auto-installs if missing on lines 27-31).
  2. Git Tagging – Creates an annotated tag in the format v${VERSION} and pushes it to origin.
  3. CI Trigger – The .github/workflows/release.yaml workflow detects the new tag, builds Rust binaries for all supported platforms, and attaches them to the GitHub release.

After the CI completes, users can download binaries from URLs following the pattern: https://github.com/dmtrKovalenko/fff.nvim/releases/download/<TAG>/<TRIPLE>.<EXT>

Troubleshooting Update Issues

Binary Locked on Windows

On Windows, if Neovim holds a lock on the old DLL, the atomic update may fail. The downloader writes to a .tmp file first, then attempts to rename it. If this fails, vim.notify emits a warning (lines 33-38 in download.lua). Restart Neovim to release the lock and allow the update to complete.

Missing Platform Binaries

If your architecture lacks a pre-built release asset, check the GitHub releases page. If your target triple is missing, run :lua require('fff.download').build_binary() to compile locally, provided you have rustup and Cargo installed.

Debug Logging

Update operations log to vim.fn.stdpath('log') .. '/fff.log'. Inspect this file using the :FFFOpenLog command to diagnose download failures or version mismatches.

Summary

  • Plugin manager updates rely on the build hook calling download_or_build_binary() in lua/fff/download.lua, which attempts to download pre-built assets before falling back to local compilation.
  • Manual updates use ensure_downloaded({force = true}) to refresh binaries on demand, or build_binary() for source compilation.
  • Release authoring requires running scripts/release.sh to bump the crate version in Cargo.toml, create Git tags, and trigger GitHub Actions.
  • All binary downloads target the release tag determined by lua/fff/utils/version.lua, supporting both stable and prerelease channels.

Frequently Asked Questions

How do I force fff.nvim to download a fresh binary without reinstalling the plugin?

Run :lua require('fff.download').ensure_downloaded({force = true}) from Neovim. This bypasses the local cache and re-downloads the asset matching your current plugin version tag from GitHub releases.

What happens if there is no pre-built binary for my operating system?

The downloader automatically falls back to building from source. Ensure you have Rust installed (via rustup), then the build_binary() function will compile the Rust component locally using cargo build --release.

Can I update the binary without restarting Neovim?

Yes, by running the Lua commands manually. However, on Windows, if the previous binary is loaded into memory, you must restart Neovim to release the file lock before the new binary can take effect.

Where does fff.nvim store its update logs?

The plugin writes detailed operation logs to the path returned by vim.fn.stdpath('log') .. '/fff.log'. Access this file directly or use the :FFFOpenLog command to review download attempts, build errors, and version resolution details.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →