I have a low tolerance for terminal tools that promise to replace something I already use fifty times a day. fzf earned its place in my dotfiles years ago and it has never given me a reason to look elsewhere. So when I kept seeing television show up in Rust CLI roundups, my honest first reaction was skepticism. Another fuzzy finder? What is left to improve? I installed it expecting to uninstall it by the end of the week. Two months later the tv command is still on my machine, and I have opinions.
What television actually is
Television, built by Alex Pasmantier, is a fuzzy finder TUI written in Rust. At the surface it does the same job as fzf: you give it a list of things, you type, and it filters them in real time with fuzzy matching, then you pick one. You bind it to keystrokes, pipe commands into it, and use it to fly through files, git history, processes, and anything else that can be expressed as a list of lines.
The pitch that sets it apart is the concept of channels. In fzf, every use is an ad-hoc pipeline: you write fd --type f | fzf or git log --oneline | fzf and wire the preview and keybindings inline each time, usually buried in a shell alias. Television flips that around. A channel is a named, reusable source defined in config: it knows what command produces its data, how to preview a selected entry, and what keys do what. Once you have defined a files channel or a git-log channel, you just run tv files or tv git-log. The plumbing lives in one place instead of scattered across your dotfiles.
That is the core philosophical difference. fzf is a brilliant primitive you compose yourself. Television wants to be a small framework of curated, shareable pickers.
Installing it
Getting the tv binary took me under a minute. If you have a Rust toolchain, cargo is the direct route:
cargo install television
On macOS or Linuxbrew, Homebrew is simpler and does not need Rust installed:
brew install television
There are also prebuilt binaries on the GitHub releases page and packages in a few distro repos, but cargo and brew are the paths I would point most people to. Once installed, confirm it works and check the version:
tv --version
The one step people skip and then complain about is shell integration. Television ships init scripts that wire up the keybindings, and you have to source them. For zsh, add this to your .zshrc:
eval "$(tv init zsh)"
For bash it is tv init bash in your .bashrc, and for fish it is tv init fish in config.fish. After you reload the shell you get two bindings that will feel familiar to fzf users: ctrl-t to fuzzy-find files and paste the selection onto the command line, and ctrl-r to fuzzy-search shell history. Those two keys alone are most of the day-to-day value.
How it actually differs from fzf
After living with both, here is where television genuinely diverges rather than just repackaging.
Previews are a first-class citizen. With fzf you bolt on a preview with --preview 'bat --color=always {}' and manage the syntax highlighting yourself. Television treats previewers as a defined concept. Point a channel at a previewer and it renders syntax-highlighted file contents, git diffs, or command output in the side pane without you assembling the pipeline. Out of the box the file preview is highlighted and readable, which is the state most fzf users eventually configure their way to anyway.
The cable system. Channels are distributed through what the project calls cable, a directory of TOML channel definitions you can drop in and immediately use. Community channels cover common sources so you are not reinventing a git-branch picker for the hundredth time. It is a small ecosystem, but the idea of pulling in a ready-made picker instead of writing shell glue is the right one.
Async rendering on huge inputs. On a monorepo where fd returns hundreds of thousands of paths, television streams and renders matches asynchronously so the UI stays responsive while the source is still producing. fzf handles big inputs fine too, but television felt snappier under those conditions in my testing. Both are ultimately limited by how fast fd or ripgrep feeds them, so do not expect magic, but the finder is not the bottleneck.
History search. The ctrl-r integration is genuinely nice, giving you a fuzzy TUI over shell history with preview. If you already run Atuin you may not need it, but for a stock shell it is a real upgrade over the default reverse search.
Configuring channels
This is where television asks a bit more of you than fzf does, and also where it pays you back. Configuration lives under your config directory, typically ~/.config/television/, with a main config.toml and channel definitions. A minimal channel is just a source command plus an optional preview. Here is a files channel that uses fd to enumerate paths and bat to preview them:
[[cable_channel]]
name = "files"
source_command = "fd --type f --hidden --exclude .git"
preview_command = "bat --style=numbers --color=always {}"
The {} placeholder is the selected entry, the same convention fzf uses. Invoke it with tv files. A git-log channel is just as short and shows how the preview can run an arbitrary command against the selection:
[[cable_channel]]
name = "git-log"
source_command = "git log --oneline --date=short --pretty='%h %s'"
preview_command = "git show --color=always {1}"
Here {1} refers to the first whitespace-delimited field, the commit hash, so the preview pane renders the full diff of whatever commit you have highlighted. An environment-variable channel is a nice quality-of-life pick for when you are debugging why some tool is not seeing the value you expect:
[[cable_channel]]
name = "env"
source_command = "env"
preview_command = "echo {}"
The general config file controls global behavior: the default channel, theme, keybindings, and preview layout. You do not have to touch it to be productive, but it is where you would set your color theme or change the preview pane size. Copy a starter config from the repo, trim what you do not need, and you are running.
The workflows that stuck
Configuration is theory. Here is what I actually do with it.
Jumping to files. The ctrl-t binding is my most-used interaction by a wide margin. I start typing a command, hit ctrl-t, fuzzy-match a path with a live syntax-highlighted preview confirming it is the right file, and the path lands on my command line. This replaced a hand-rolled fzf binding I had carried across three machines, and television’s version needed no configuration to look good.
Browsing git history. tv git-log with the channel above has become my default way to spelunk through a branch. I scroll commit subjects on the left, the diff renders on the right, and when I find the commit I want I select it to drop the hash into my command for a git revert or git cherry-pick. It is faster than git log -p piped through a pager.
Ripgrep integration. The workflow I did not expect to love is content search. Feed television the output of ripgrep and you get an interactive filter over matching lines across the repo, with a preview of the surrounding code:
rg --line-number --no-heading . | tv
Select a line and you have the file and line number to jump to in your editor. It is grep-driven code navigation without leaving the terminal, and on a large codebase the async rendering keeps it usable while ripgrep is still churning.
Environment and process poking. The env channel and a quick process channel over ps are the kind of small tools I never bothered to build in fzf because the pipeline was annoying to remember. Defining them once as channels means they are always a tv env away. That is the channel model delivering on its promise: the friction of the second, third, and fourth use drops to nearly zero.
The honest cons
I would not be doing my job if I only told you the good parts.
It is younger and less battle-tested than fzf. fzf has a decade of production hardening, an enormous user base, and integration into countless tools and scripts. Television is comparatively new. I hit no data-loss or crash issues in two months, but the surface area of edge cases fzf has already ironed out is simply larger. For anything mission-critical or shared with a team, that maturity gap matters.
The config has a learning curve. fzf’s genius is that you can be productive with zero config by just piping into it. Television rewards configuration, which means the payoff comes after you sit down and define channels. If you want it to shine you will spend an evening with the TOML and the docs. That is a fair trade for what you get, but it is real upfront cost, and the documentation, while decent, occasionally lags the current behavior.
Some rough edges. The CLI flags and channel format are still evolving, so a config that works today might need a tweak after a major update. I ran into a couple of small inconsistencies between what a flag did and what I expected, and preview layout options took some trial and error. None were blockers, but you can feel that this is a fast-moving project rather than a frozen, finished one.
It overlaps with tools you may already run. If you already have fzf plus Atuin plus a curated set of aliases, television’s marginal benefit is smaller. It is most compelling as a cohesive replacement, not as one more layer on an already crowded setup.
The Bottom Line
Television is a genuinely good fuzzy finder, and the channel and cable model is a smart, opinionated take on a problem fzf solves with raw composability. The previews look great with no effort, it stays fast on enormous repos, and once you have defined a handful of channels the ergonomics are a real step up from maintaining a pile of shell aliases. I went in expecting to uninstall it and it is still here, which is the strongest thing I can say.
But I want to be precise about the recommendation. This is not a slam-dunk replacement for everyone. If your fzf setup works and your muscle memory is deep, there is no urgent reason to switch, and for shared scripts and CI I still reach for fzf because of its maturity. Television is worth adopting if you like the channel concept, want highlighted previews for free, or simply enjoy trying the well-built Rust CLI tools of this era. It is one of the good ones.
So: keep fzf where stability matters, install television for your personal interactive use, and give the channel system a real evening before you judge it. That is where it earns its keep. Two months in, tv has a permanent spot in my dotfiles, and that bar is high.