- Published on
- · 14 min read
Yazi: The Blazing-Fast Terminal File Manager for Developers
Yazi: The Blazing-Fast Terminal File Manager for Developers
If you spend most of your day in the terminal — navigating projects, previewing files, managing directories — you've probably used ls, cd, and tree thousands of times. Terminal file managers like Ranger have existed for years, but they share a fundamental problem: synchronous I/O. Open a directory with 10,000 files and the UI freezes.
Yazi (meaning "duck" in Chinese) solves this with a fully async, Rust-powered architecture. Every I/O operation is non-blocking. Directories load progressively. Image previews render natively. And it ships with a Lua plugin system and built-in package manager so you can extend it however you want.
With 33k+ GitHub stars and rapid iteration since its 2023 launch, Yazi has become the default terminal file manager for developers who care about speed.
Table of Contents
- Why Yazi
- Installation
- Core Concepts
- Complete Keybinding Reference
- Configuration
- Plugin Ecosystem
- Tool Integrations
- Practical Workflows
- Yazi vs Ranger vs lf vs nnn
- Resources
Why Yazi
Six things set Yazi apart from every other terminal file manager:
- Fully async I/O — All file operations (listing, copying, previewing) run on background threads. The UI never freezes, even in massive directories.
- Native image preview — Built-in support for Kitty Graphics Protocol, Sixel, iTerm2 Inline Images, and Ghostty. No hacky Uberzug workarounds needed (though it supports Uberzug++ as a fallback).
- Scrollable previews — Preview text files, images, PDFs, videos, archives, JSON, and Jupyter notebooks. Scroll through content without opening the file.
- Lua plugin system — Write functional plugins, custom previewers, metadata fetchers, and preloaders in Lua 5.4. There's a built-in package manager (
ya pkg) for installing community plugins. - Vim-style keybindings — If you know vim motions, you already know Yazi.
hjklnavigation, visual mode, yanking, and marks all work as expected. - Multi-tab and task management — Open multiple directory tabs, run file operations in the background with real-time progress, and cancel tasks on the fly.
Installation
macOS (Homebrew)
brew install yazi ffmpeg sevenzip jq poppler fd ripgrep fzf zoxide imagemagick font-symbols-only-nerd-fontUbuntu / Debian
There's no official apt package with guaranteed up-to-date versions. Your best options:
# Option 1: Snap
sudo snap install yazi
# Option 2: Download binary from GitHub releases
# https://github.com/sxyazi/yazi/releases
# Option 3: Build from source (requires Rust toolchain)
cargo install --force yazi-buildArch Linux
sudo pacman -S yazi ffmpeg 7zip jq poppler fd ripgrep fzf zoxide imagemagickFedora
dnf copr enable lihaohong/yazi
dnf install yaziOther Platforms
- Nix: Available in nixpkgs
- Windows:
scoop install yaziorwinget install sxyazi.yazi - Cargo (any OS):
cargo install --force yazi-build
Required and Recommended Dependencies
Yazi needs file for MIME type detection (pre-installed on most systems). For the full experience, install these optional dependencies:
| Dependency | Purpose |
|---|---|
| Nerd Font | File type icons |
| ffmpeg | Video thumbnails |
| 7-Zip | Archive preview and extraction |
| jq | JSON preview |
| poppler | PDF preview |
| fd | Filename search (s key) |
| ripgrep | Content search (S key) |
| fzf | Fuzzy file finding (z key) |
| zoxide | Smart directory jumping (Z key) |
| ImageMagick | HEIC, JPEG XL, font preview |
Shell Wrapper (cd on exit)
By default, quitting Yazi doesn't change your shell's working directory. Add this wrapper function to your .zshrc or .bashrc:
function y() {
local tmp="$(mktemp -t "yazi-cwd.XXXXXX")" cwd
yazi "$@" --cwd-file="$tmp"
if cwd="$(command cat -- "$tmp")" && [ -n "$cwd" ] && [ "$cwd" != "$PWD" ]; then
builtin cd -- "$cwd"
fi
rm -f -- "$tmp"
}Now use y instead of yazi. When you quit with q, your shell cds into whatever directory you were browsing.
Core Concepts
Yazi uses a three-pane layout inspired by Ranger:
┌──────────┬──────────────┬──────────────┐
│ Parent │ Current │ Preview │
│ dir │ dir │ of file │
│ │ │ │
│ │ > file.ts │ [contents] │
│ │ lib/ │ │
│ │ tests/ │ │
└──────────┴──────────────┴──────────────┘
- Left pane: Parent directory (context for where you are)
- Center pane: Current directory (where your cursor is)
- Right pane: Preview of the hovered file or directory contents
Navigate with hjkl — h goes up a directory, l enters a directory or opens a file, j/k move the cursor down/up.
Tabs
Yazi supports multiple tabs, numbered 1–9. Press t to create a new tab, 1–9 to switch instantly. Think of it like browser tabs for your filesystem.
Tasks
File operations (copy, move, delete) run as background tasks with real-time progress. Press w to open the task manager, x to cancel a task.
Visual Mode
Press v to enter visual mode — select ranges of files with j/k, then operate on the selection (yank, cut, delete, etc.). Works exactly like vim visual line mode.
Complete Keybinding Reference
Navigation
| Key | Action |
|---|---|
j / k | Move cursor down / up |
l / h | Enter directory (or open file) / Go to parent |
H / L | Go back / Go forward (history) |
gg | Jump to top of list |
G | Jump to bottom of list |
Ctrl+d / Ctrl+u | Half-page down / up |
Ctrl+f / Ctrl+b | Full page down / up |
J / K | Scroll preview pane down / up |
Quick Directory Access
| Key | Action |
|---|---|
gh | Go to home directory (~) |
gc | Go to config directory |
gd | Go to downloads directory |
g Space | Interactive directory change (type a path) |
z | Fuzzy find via fzf |
Z | Smart jump via zoxide |
File Operations
| Key | Action |
|---|---|
o / Enter | Open file |
O | Open interactively (choose program) |
y | Yank (copy) selected files |
x | Cut selected files |
p | Paste files |
P | Paste (overwrite if exists) |
Y / X | Cancel yank / cut |
d | Trash files (soft delete) |
D | Permanently delete files |
a | Create new file or directory |
r | Rename file |
- | Create symlink (absolute path) |
_ | Create symlink (relative path) |
. | Toggle hidden files |
Selection
| Key | Action |
|---|---|
Space | Toggle selection on current file |
v | Enter visual mode (select range) |
V | Enter visual mode (unset range) |
Ctrl+a | Select all files |
Ctrl+r | Inverse selection |
Esc | Cancel selection |
Copy Paths to Clipboard
| Key | Action |
|---|---|
cc | Copy full file path |
cd | Copy directory path |
cf | Copy filename |
cn | Copy filename without extension |
Filter, Find, and Search
| Key | Action |
|---|---|
f | Filter files (live filtering as you type) |
/ | Incremental find (next match) |
? | Incremental find (previous match) |
n / N | Next / previous find match |
s | Search filenames with fd |
S | Search file contents with ripgrep |
Ctrl+s | Cancel search |
Sorting
| Key | Action |
|---|---|
,m / ,M | Sort by modified time / reverse |
,b / ,B | Sort by birth (creation) time / reverse |
,e / ,E | Sort by extension / reverse |
,a / ,A | Sort alphabetically / reverse |
,n / ,N | Sort naturally / reverse |
,s / ,S | Sort by size / reverse |
,r | Sort randomly |
Tab Management
| Key | Action |
|---|---|
t | Create new tab |
1–9 | Switch to tab N |
[ / ] | Previous / next tab |
{ / } | Swap with previous / next tab |
Ctrl+c | Close current tab |
Shell and Tasks
| Key | Action |
|---|---|
; | Run shell command (non-blocking) |
: | Run shell command (blocking, waits for exit) |
w | Open task manager |
~ / F1 | Open help menu |
q | Quit (writes CWD for shell wrapper) |
Q | Quit without writing CWD |
Configuration
Yazi uses three TOML config files in ~/.config/yazi/:
yazi.toml — Core Settings
[mgr]
ratio = [1, 4, 3] # Pane width ratios [parent, current, preview]
sort_by = "natural" # natural, mtime, extension, alphabetical, size
sort_dir_first = true # Directories listed before files
show_hidden = false # Show dotfiles
scrolloff = 5 # Cursor padding from edge
linemode = "none" # none, size, mtime, permissions, owner
[preview]
wrap = "no" # Line wrapping in preview
tab_size = 2 # Tab width in preview
max_width = 600 # Max image preview width
max_height = 900 # Max image preview height
[opener]
edit = [
{ run = '${EDITOR:-vi} "$@"', block = true, desc = "Edit" },
]keymap.toml — Custom Keybindings
Add keybindings without overriding defaults using prepend_keymap:
[mgr]
prepend_keymap = [
# Quick directory jumps
{ on = ["g", "r"], run = "cd ~/repos", desc = "Go to repos" },
{ on = ["g", "p"], run = "cd ~/projects", desc = "Go to projects" },
# Open lazygit
{ on = ["<C-g>"], run = "shell 'lazygit' --block", desc = "Open lazygit" },
]theme.toml — Colors and Styling
Override any visual element. For pre-made themes, install a flavor:
# Install the Catppuccin Mocha flavor
ya pkg add yazi-rs/flavors:catppuccin-mocha
# Set it in theme.toml
[flavor]
dark = "catppuccin-mocha"
light = "catppuccin-latte"Browse available flavors at yazi-rs/flavors.
init.lua — Plugin Initialization
This Lua file runs on startup. Use it to configure plugins:
-- ~/.config/yazi/init.lua
-- Enable zoxide database updates when navigating
require("zoxide"):setup { update_db = true }
-- Enable git status indicators
require("git"):setup { order = 1500 }Plugin Ecosystem
Yazi has a thriving plugin ecosystem with 150+ community plugins. The built-in ya pkg package manager handles installation, updates, and version pinning.
Installing Plugins
# Install from the official plugins monorepo
ya pkg add yazi-rs/plugins:git
ya pkg add yazi-rs/plugins:smart-enter
# Install from a standalone community repo
ya pkg add Lil-Dank/lazygit
# List installed packages
ya pkg list
# Update all packages
ya pkg upgrade
# Remove a package
ya pkg delete yazi-rs/plugins:git
# Install all packages from package.toml (fresh machine setup)
ya pkg installPlugins are tracked in ~/.config/yazi/package.toml, so you can version-control your plugin list and replicate it across machines.
Essential Plugins
These are the plugins I'd install on any new setup:
git.yazi — Git Status in File Listings
Shows modified/staged/untracked/ignored status inline next to every file:
ya pkg add yazi-rs/plugins:gitConfigure in init.lua:
require("git"):setup { order = 1500 }Add the fetchers in yazi.toml:
[[plugin.prepend_fetchers]]
id = "git"
url = "*"
run = "git"
[[plugin.prepend_fetchers]]
id = "git"
url = "*/"
run = "git"lazygit.yazi — Full Git UI
Launch lazygit from within Yazi for staging, committing, rebasing, and more:
ya pkg add Lil-Dank/lazygitsmart-enter.yazi — Context-Aware Enter
Opens files or enters directories with a single key press:
ya pkg add yazi-rs/plugins:smart-enterfull-border.yazi — Visual Borders
Adds clean visual borders around all panes:
ya pkg add yazi-rs/plugins:full-borderConfigure in init.lua:
require("full-border"):setup()chmod.yazi — File Permissions
Change file permissions directly from Yazi:
ya pkg add yazi-rs/plugins:chmoddiff.yazi — File Comparison
Compare files and create patches:
ya pkg add yazi-rs/plugins:diffMore Notable Community Plugins
| Plugin | Description | Install |
|---|---|---|
| starship.yazi | Starship prompt in Yazi header | ya pkg add Rolv-Apneseth/starship |
| yatline.yazi | Fully customizable header and status lines | ya pkg add imsi32/yatline |
| relative-motions.yazi | Vim relative line number jumps | ya pkg add dedukun/relative-motions |
| yamb.yazi | Persistent bookmarks with fzf | ya pkg add h-hg/yamb |
| projects.yazi | Save/restore tab sessions | ya pkg add MasouShizuka/projects |
| sudo.yazi | Execute operations with sudo | ya pkg add TD-Sky/sudo |
| bypass.yazi | Auto-skip single-subdirectory dirs | ya pkg add Rolv-Apneseth/bypass |
| compress.yazi | Create archives from selections | ya pkg add KKV9/compress |
| glow.yazi | Preview markdown with glow | ya pkg add Reledia/glow |
For the full list, check out awesome-yazi.
Writing Custom Plugins
Yazi plugins are Lua 5.4 scripts. Create a directory in ~/.config/yazi/plugins/ with an init.lua file:
~/.config/yazi/plugins/my-plugin.yazi/
init.lua
Here's a minimal example that copies the current directory structure to clipboard (useful for giving context to an LLM):
-- ~/.config/yazi/plugins/tree-to-clipboard.yazi/init.lua
local M = {}
function M:entry()
local cwd = tostring(cx.active.current.cwd)
local output = Command("tree")
:arg("-L"):arg("3")
:arg("--gitignore")
:cwd(cwd)
:output()
if output then
ya.clipboard(output.stdout)
ya.notify {
title = "Tree copied",
content = "Directory tree copied to clipboard",
timeout = 3,
}
end
end
return MBind it in keymap.toml:
[mgr]
prepend_keymap = [
{ on = ["g", "t"], run = "plugin tree-to-clipboard", desc = "Copy tree to clipboard" },
]For type checking and autocomplete in your editor, install the types plugin:
ya pkg add yazi-rs/plugins:typesTool Integrations
tmux
For image previews to work inside tmux, add to your .tmux.conf:
set -g allow-passthrough on
set -ga update-environment TERM
set -ga update-environment TERM_PROGRAMNeovim
yazi.nvim provides deep bidirectional integration. Files hovered in Yazi are highlighted in Neovim, and you can open files as buffers, splits, or tabs directly from Yazi.
zoxide
Enable automatic database updates so every directory you visit in Yazi gets added to zoxide's ranking:
-- init.lua
require("zoxide"):setup { update_db = true }fzf and ripgrep
Both are built-in integrations — no plugin needed. Just have fzf, fd, and ripgrep in your $PATH:
z— Fuzzy find files with fzfs— Search filenames with fdS— Search file contents with ripgrep
Practical Workflows
TypeScript / Web Development
Navigating a monorepo: Open tabs for different packages. Tab 1 for apps/web, tab 2 for packages/ui, tab 3 for packages/api. Press 1, 2, 3 to switch instantly.
Finding components: Press / and start typing a component name. Yazi incrementally narrows the file list as you type. Faster than Ctrl+P in VS Code for large projects because it doesn't index — it just filters what's on screen.
Previewing configs: Navigate to tsconfig.json, package.json, .env.local, or next.config.js and read the contents in the preview pane without opening your editor. Sort by modified time (,m) to see what changed recently.
Reviewing build output: Navigate to .next/, dist/, or node_modules/.cache to inspect build artifacts. The preview pane renders JSON, JavaScript, and source maps inline.
Bulk rename: Need to rename a batch of component files from PascalCase to kebab-case? Select files with v and visual mode, press r to open the bulk rename buffer in your $EDITOR, then use vim macros or find-and-replace to transform all names at once.
Linux Server Administration
Log inspection: Navigate to /var/log/ and preview log files inline. Sort by modified time (,m) to see the most recent logs first. Search within log content with S to grep across all log files.
Config file management: Jump between /etc/nginx/, /etc/systemd/, and /home/deploy/ using zoxide (Z). Preview config files before editing — catch mistakes before they take down a service.
Permission management: Use the chmod.yazi plugin to change permissions visually. Set linemode to permissions in yazi.toml to see file permissions inline:
[mgr]
linemode = "permissions"Remote file management: Use sshfs.yazi to mount remote directories over SSH and browse them like local files.
Disk management: Use mount.yazi to mount, unmount, and eject disks without dropping to a shell.
AI-Assisted Development (Claude Code, Cursor, etc.)
When an AI coding agent is autonomously editing your codebase, Yazi becomes your real-time visibility layer:
Monitor file changes: Keep Yazi open alongside your AI agent. Sort by modified time (,m) and you'll see files bubble to the top as the agent modifies them. The preview pane shows the current contents instantly — no need to cat or open each file.
Review generated files: After an agent generates code, navigate to the output directory and scroll through each file's contents in the preview pane. Faster than opening each file individually in an editor.
Git status awareness: With git.yazi enabled, you see which files are modified, staged, or untracked right in the file listing. After an AI agent makes changes, you can immediately see the blast radius.
Copy directory context for prompts: Use the shell command (:) to run tree --gitignore -L 3 | pbcopy and paste the directory structure into your LLM conversation. Or write a custom plugin (like the tree-to-clipboard example above) to do it with a keybinding.
Bulk review and clean up: After an agent creates files you don't want, select them in visual mode (v), then trash (d) or permanently delete (D). Faster than rm-ing files one by one.
Quick diff: Use the diff.yazi plugin to compare the agent's output against your original files.
Yazi vs Ranger vs lf vs nnn
| Feature | Yazi | Ranger | lf | nnn |
|---|---|---|---|---|
| Language | Rust + Lua | Python | Go | C |
| I/O model | Fully async | Synchronous | Async dir loading | Synchronous |
| Large directory performance | Excellent | Sluggish (10k+ files) | Fast | Fastest |
| Image preview | Native (Kitty, Sixel, iTerm2) | Uberzug only | External scripts | None |
| Plugin system | Lua + built-in pkg manager | Python scripts | Shell scripts | Shell scripts |
| Out-of-box experience | Excellent | Good (needs config) | Minimal | Minimal |
| File preview | Text, image, PDF, video, archive, JSON | Text, images (with setup) | Text (via script) | None |
| Tabs | Built-in (1–9) | Built-in | No | Contexts (4 max) |
| Trash support | Built-in | Limited | External | Via plugin |
| Memory usage | Low | Higher (Python) | Very low | Lowest (~3.5MB) |
| GitHub stars | 33k+ | 16k | 8k | 19k |
Pick Yazi if you want the best async performance, image previews, and a modern plugin ecosystem that works out of the box.
Pick Ranger if you're already invested in its Python plugin ecosystem and don't mind the performance trade-off.
Pick lf if you want a minimal, Go-based file manager and prefer configuring everything via shell scripts.
Pick nnn if you need the absolute lightest footprint — ideal for SSH into constrained servers or Docker containers.
Resources
Official
- GitHub Repository — Source code, issues, discussions
- Official Documentation — Installation, configuration, plugin API
- Quick Start Guide — Get running in 5 minutes
- Configuration Reference — yazi.toml, keymap.toml, theme.toml
- Plugin Documentation — Writing and using plugins
- Image Preview Setup — Terminal-specific setup instructions
- Tips and Tricks — Advanced usage patterns
- FAQ — Common questions and troubleshooting
Plugins and Themes
- yazi-rs/plugins — Official plugin monorepo (18 plugins)
- yazi-rs/flavors — Official theme/flavor repository
- awesome-yazi — Curated list of 150+ community plugins and resources
Integrations
- yazi.nvim — Neovim integration
- lazygit.yazi — Lazygit inside Yazi
- starship.yazi — Starship prompt in Yazi