Telescope vs fzf — 퍼지 파인더의 경계선
fzf는 Neovim 없이도 도는 독립 Go 바이너리, Telescope는 Neovim API에 얹힌 순수 Lua 플러그인. 둘의 실행 경계와 fzf-lua·snacks.picker 같은 선택지를 구분한다.
Neovim 설정을 훑다 보면 파일을 퍼지 검색하는 도구로 fzf와 Telescope가 나란히 등장한다. “둘 다 파일 검색되는데 뭐가 다르지?”에서 멈추기 쉽지만, 사실 둘은 정체가 다른 물건이다. 이 글은 특정 배포판의 기본값이 아니라 fzf와 Telescope의 아키텍처 차이를 정리한다.
결론 먼저
- fzf — Go로 작성된 독립 실행 CLI 바이너리다. 셸(
Ctrl-R히스토리, 파이프 입력), Vim, tmux 어디서든 돈다. Neovim이 없어도 동작하는 게 핵심. - Telescope — Neovim 전용 순수 Lua 플러그인이다. Neovim API에 깊이 통합돼서 파일뿐 아니라 LSP 심볼, diagnostics, git, buffer, treesitter 같은 에디터 내부 데이터를 picker로 다룬다.
- 즉 갈림길은 어디서 도느냐(OS 전역 vs 에디터 내부)와 무엇을 검색 대상으로 넘기느냐다. “파일 검색”은 겹치는 기능 하나일 뿐이다.
둘 다 “파일 검색 모듈”이 아니라 퍼지 매칭 엔진이다
정확히 말하면 둘 다 fuzzy finder(퍼지 매칭 엔진)이고, 파일 검색은 여러 용도 중 하나일 뿐이다. 핵심은 무엇을 입력으로 넘기느냐.
- fzf는 그냥 “줄 목록을 받아 퍼지 매칭해주는 엔진”이다. 파일 목록을 넣으면 파일 검색, 셸 히스토리를 넣으면 히스토리 검색,
git branch출력을 넣으면 브랜치 검색. 검색 대상이 뭐든 상관 안 한다. - Telescope도 같은 구조인데, 대신 Neovim 안의 것들(LSP 심볼, diagnostics, buffer 등)을 검색 대상으로 쉽게 꽂을 수 있게 picker들이 미리 만들어져 있다.
비유하면 전기포트와 가스레인지가 둘 다 물을 끓일 수 있다고 같은 물건은 아니다. 겹치는 기능 하나로 보면 같아 보여도, fzf는 OS 전역 도구, Telescope는 에디터 내장 데이터까지 다루는 통합 도구라는 게 본질이다.
어디까지가 Neovim 내부이고 어디부터 외부 프로세스인가
Telescope가 순수 Lua라고 해서 혼자 다 하는 건 아니다. 경계가 둘로 나뉜다.
- Lua 레벨 의존성 (Neovim 내부) —
plenary.nvim이 유일한 진짜 의존성이다. 비동기 처리(async/await), job 제어, 경로 처리, 파일시스템 함수 등 Telescope의 거의 모든 내부 동작이 그 위에 올라간다. 없으면 Telescope 자체가 로드되지 않는다.nvim-web-devicons는 아이콘용 선택 의존성. - 런타임에 부르는 시스템 바이너리 (외부 프로세스) — picker별로 외부 CLI를 spawn 한다.
live_grep/grep_string은 ripgrep(rg)를 내부적으로 호출(사실상 필수급), 파일 검색은 fd를 빠른 대안으로, git picker는 git을 부른다. 이건 Lua 의존성이 아니라 시스템 도구다.
즉 Telescope는 “Lua로 짠 picker/preview 프레임워크(내부) + 무거운 검색은 외부 바이너리에 위임” 구조다. fzf가 통째로 외부 프로세스인 것과 대비된다.
핵심 트레이드오프
| 축 | fzf | Telescope |
|---|---|---|
| 범위 | OS 전역 | Neovim 내부 |
| 언어/통합 | 외부 바이너리 | Lua 네이티브 |
| 속도 | 대형 저장소에서 빠른 경향(네이티브) | 상대적으로 느림 |
| 확장성 | 범용 | Neovim 생태계(LSP 등) 연동 압도적 |
둘을 섞는 선택지
경계를 이해하면 “둘 중 하나”가 아니라 섞는 조합도 보인다.
- telescope-fzf-native.nvim — Telescope의 정렬 알고리즘을 fzf의 C 구현으로 바꿔 속도를 끌어올리는 확장. C로 컴파일되므로
make가 필요하다. picker UI는 Telescope 그대로, 매칭만 빨라진다. - fzf-lua — fzf 바이너리를 Telescope처럼 Neovim picker로 감싼 플러그인. fzf의 속도 + 에디터 통합을 둘 다 가져간다. 가볍고 빠른 쪽을 원할 때 매력적이다.
현재 kickstart.nvim도 Telescope + fzf-native 조합을 예제로 사용한다. 이 구성은 Telescope UI와 확장 생태계를 유지하면서 native sorter를 붙이는 선택이다.
선택지 확장 — snacks.picker와 mini.pick
plenary.nvim은 Telescope의 현재 필수 의존성이고 저장소도 archived 상태가 아니다. 따라서 유지보수 종료를 전제로 Telescope의 미래를 단정할 근거는 없다. 다만 picker 선택지는 늘었다. folke의 snacks.picker는 LazyVim 새 설치의 fallback 기본 선택이고, mini.pick은 독립적인 소형 picker를 제공한다. LazyVim에서는 :LazyExtras로 snacks·fzf-lua·Telescope 중 하나를 선택할 수 있다.
정리하면 퍼지 파인더 선택지가 셋으로 갈라졌다.
| 선택지 | 성격 | 의존성 | 결 |
|---|---|---|---|
| Telescope | 성숙한 확장 생태계 | plenary | 기능 폭이 넓고 kickstart 예제로도 사용 |
| snacks.picker | LazyVim 새 설치의 fallback 기본 | snacks.nvim 내부 모듈 | LazyVim과 통합이 깊음 |
| mini.pick | echasnovski의 독립 모듈 | 없음(zero-dep) | 보수적·미니멀, 모듈 독립성 |
여기에 fzf-lua는 fzf 기반 성능과 Neovim 통합을 함께 원하는 선택지다.
어느 하나가 “정답”은 아니다. 성숙한 확장 생태계면 Telescope, LazyVim의 기본 선택을 따르면 snacks.picker, 작은 독립 모듈이면 mini.pick, fzf 실행 엔진을 원하면 fzf-lua가 자연스럽다.
함정 정리
- “둘 다 파일 검색된다”로 같은 물건 취급하지 말 것 — fzf는 OS 전역 도구, Telescope는 에디터 내부 데이터 통합 도구다.
- Telescope는 순수 Lua라도
ripgrep/fd/git을 런타임에 spawn한다.live_grep이 안 되면 대개rg미설치가 원인. plenary.nvim은 선택이 아니라 필수 의존성이다. 없으면 Telescope가 아예 로드되지 않는다.nvim-web-devicons만 선택 의존성.telescope-fzf-native.nvim은make컴파일이 필요하다 — 빌드가 빠지면 정렬 가속이 안 걸린다.
더 깊이
- fzf 공식 저장소 — 셸/Vim/tmux 통합 예시
telescope.nvim,plenary.nvim,telescope-fzf-native.nvim,fzf-lua각 저장소 README- ripgrep(
rg) / fd 문서 — Telescope가 위임하는 검색 백엔드