← Back to articles

How Telescope Works - Can It Use fzf

Path: Computer Tech/Development/Editors/Neovim/How Telescope Works - Can It Use fzf.mdUpdated: 2/3/2026

How Telescope Works: Can It Use fzf?

Short answer: No, Telescope cannot use your external fzf binary. It's a pure Lua implementation built specifically for Neovim.

But that's actually a good thing! Here's why.

Telescope Architecture

What Telescope Is

Telescope is 100% Lua code running inside Neovim - it doesn't call external programs.

Telescope Architecture:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         Neovim (LuaJIT)             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚      Telescope (Lua)          β”‚  β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚  β”‚
β”‚  β”‚  β”‚ Finder  β”‚  β”‚  Sorter  β”‚   β”‚  β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚  β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚  β”‚
β”‚  β”‚  β”‚Previewerβ”‚  β”‚   UI     β”‚   β”‚  β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         All Lua - No fzf!

Key components:

  1. Finder - Gets the list of items (files, buffers, LSP symbols, etc.)
  2. Sorter - Fuzzy matching algorithm (pure Lua)
  3. Previewer - Shows file preview (using Vim buffers)
  4. UI - Floating windows (Neovim API)

What fzf Is

fzf Architecture:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         Your Shell (zsh)            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   fzf (Native Binary - Go)    β”‚  β”‚
β”‚  β”‚   - Fast C-based matching     β”‚  β”‚
β”‚  β”‚   - Terminal UI (ncurses)     β”‚  β”‚
β”‚  β”‚   - Reads stdin, writes stdoutβ”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       Native Go program

Can Telescope Use fzf? No.

Why not:

  1. Different languages: Telescope is Lua, fzf is Go
  2. Different environments: Telescope runs inside Neovim, fzf runs in terminal
  3. Different architecture: Telescope uses Neovim APIs, fzf uses ncurses
  4. By design: Telescope was built to be pure Lua/Neovim

There's no bridge between them - they're fundamentally different tools.

What About FZF_DEFAULT_COMMAND?

Your FZF_DEFAULT_COMMAND is for the CLI fzf only - it doesn't affect Telescope.

bash
# This only affects terminal fzf
export FZF_DEFAULT_COMMAND='rg --files --hidden'

# Terminal usage:
fzf          # Uses FZF_DEFAULT_COMMAND βœ…
rfv TODO     # Uses fzf β†’ Uses FZF_DEFAULT_COMMAND βœ…

# Neovim usage:
:Telescope find_files    # Does NOT use FZF_DEFAULT_COMMAND ❌

How Telescope Finds Files

Telescope has its own file discovery - it doesn't use your fzf settings.

Default File Discovery

lua
-- Telescope's built-in file finder uses:
1. ripgrep (rg --files) if available
2. fd if available
3. find as fallback

Note: Telescope respects .gitignore by default when using ripgrep!

Configuring Telescope File Discovery

You CAN configure what Telescope uses to find files:

lua
-- ~/.config/nvim/lua/plugins/telescope.lua
return {
  "nvim-telescope/telescope.nvim",
  opts = {
    defaults = {
      -- vimgrep_arguments affects live_grep
      vimgrep_arguments = {
        "rg",
        "--color=never",
        "--no-heading",
        "--with-filename",
        "--line-number",
        "--column",
        "--smart-case",
        "--hidden",  -- Add this for hidden files
      },
    },
    pickers = {
      find_files = {
        -- Configure find_files specifically
        find_command = { "rg", "--files", "--hidden", "--glob", "!.git/*" },
        -- This is YOUR fzf command, but for Telescope!
      },
    },
  },
}

This achieves the same goal as FZF_DEFAULT_COMMAND!

Telescope Fuzzy Matching: Can It Use fzf Algorithm?

Yes and no.

Default: Pure Lua Sorter

Telescope uses its own fuzzy matching algorithm written in Lua:

lua
-- Default sorter (pure Lua)
require('telescope.config').defaults.file_sorter

Pros:

  • βœ… Fast enough for most use cases
  • βœ… No dependencies
  • βœ… Works everywhere

Cons:

  • ❌ Slower than native fzf
  • ❌ Different matching behavior than fzf

Option: telescope-fzf-native.nvim

You CAN use fzf's matching algorithm (not the binary, but the algorithm)!

telescope-fzf-native.nvim is a compiled C extension that implements fzf's matching algorithm for Telescope.

lua
-- Add to your LazyVim plugins
return {
  "nvim-telescope/telescope-fzf-native.nvim",
  build = "make",  -- Compiles C code
  config = function()
    require("telescope").load_extension("fzf")
  end,
}

What this does:

  • βœ… Uses fzf's fuzzy matching algorithm (same scoring as CLI fzf)
  • βœ… Compiled C code (faster than pure Lua)
  • βœ… Integrated into Telescope seamlessly
  • ❌ Still doesn't use your FZF_DEFAULT_COMMAND or FZF_DEFAULT_OPTS

Performance boost:

  • Pure Lua sorter: ~150ms for 10,000 files
  • fzf-native sorter: ~30ms for 10,000 files

Comparison Table

FeatureCLI fzfTelescopefzf-lua
Uses external fzf binaryβœ… (it IS fzf)βŒβœ…
Uses FZF_DEFAULT_COMMANDβœ…βŒβœ… (optional)
Uses FZF_DEFAULT_OPTSβœ…βŒβœ… (optional)
Fuzzy matchingfzf algorithmLua (or fzf-native)fzf algorithm
Integration with NeovimNoneDeep (LSP, Git, etc.)Good
Pure Lua❌ (Go)βœ…βŒ (calls fzf)

fzf-lua: The Bridge Between Worlds

If you want to use YOUR fzf in Neovim, use fzf-lua instead of Telescope!

lua
-- fzf-lua actually calls your fzf binary
:FzfLua files

-- Under the hood:
-- 1. Generates file list (using rg, fd, or find)
-- 2. Pipes to fzf binary
-- 3. fzf uses YOUR FZF_DEFAULT_OPTS
-- 4. Returns result to Neovim

This DOES use:

  • βœ… Your FZF_DEFAULT_OPTS (preview settings, keybindings)
  • βœ… Your configured fzf binary
  • βœ… Same UX as terminal fzf

See Telescope vs fzf-lua for Neovim for details.

So What Should You Do?

Option 1: Use Telescope (Recommended)

Configure it to match your fzf workflow:

lua
-- ~/.config/nvim/lua/plugins/telescope.lua
return {
  {
    "nvim-telescope/telescope.nvim",
    dependencies = {
      "nvim-telescope/telescope-fzf-native.nvim",
      build = "make",
    },
    opts = {
      defaults = {
        layout_strategy = "horizontal",
        layout_config = {
          horizontal = {
            preview_width = 0.6,  -- Match your rfv layout!
          },
        },
      },
      pickers = {
        find_files = {
          -- Use same command as FZF_DEFAULT_COMMAND
          find_command = { "rg", "--files", "--hidden", "--glob", "!.git/*" },
        },
      },
    },
    config = function(_, opts)
      require("telescope").setup(opts)
      require("telescope").load_extension("fzf")  -- Use fzf algorithm
    end,
  },
}

Result:

  • βœ… Fast fzf-like matching (fzf-native extension)
  • βœ… Respects .gitignore (ripgrep)
  • βœ… Deep Neovim integration
  • ❌ Still separate from terminal fzf (that's OK!)

Option 2: Add fzf-lua (For Consistency)

If you really want terminal-fzf UX in Neovim:

lua
-- Add fzf-lua alongside Telescope
return {
  "ibhagwan/fzf-lua",
  keys = {
    { "<leader>pf", "<cmd>FzfLua files<cr>" },
    { "<leader>pg", "<cmd>FzfLua live_grep<cr>" },
  },
}

Result:

  • βœ… Identical to terminal fzf
  • βœ… Uses FZF_DEFAULT_OPTS
  • βœ… Can coexist with Telescope
  • ❌ Less LSP/Git integration than Telescope

Common Misconceptions

❌ "Telescope uses fzf under the hood"

Reality: Telescope is pure Lua. It has its own fuzzy matcher.

❌ "FZF_DEFAULT_COMMAND affects Telescope"

Reality: That variable is only for CLI fzf. Telescope has its own config.

❌ "I need to choose between fzf and Telescope"

Reality: You can use both! Terminal fzf for shell, Telescope for editor.

βœ… "I can make Telescope behave like fzf"

Reality: YES! Configure it the same way (file discovery, layout, etc.)

Summary

Can Telescope use your fzf?

  • ❌ No - Telescope doesn't call external fzf binary
  • βœ… But - You can make it behave similarly by:
    1. Using same file discovery command (ripgrep)
    2. Installing fzf-native extension (fzf algorithm)
    3. Configuring similar layout

Should you use fzf-lua instead?

  • ⏸️ Only if you want 100% terminal-fzf consistency
  • βœ… Otherwise Telescope is better (more features, better integration)

Bottom line:

  • Keep using rfv in terminal (uses fzf)
  • Keep using Telescope in Neovim (doesn't use fzf, that's fine!)
  • Configure them similarly for consistent feel
  • They're separate tools for separate contexts

Related Articles

Links

Official Documentation