Preview images and PDFs directly inside Neovim using Sixel graphics.
Built for Windows Terminal 1.22+, but works on any sixel-capable terminal (WezTerm, foot, mlterm, etc.).
- Image preview — PNG, JPG, GIF, SVG, WebP, BMP, TIFF, ICO
- PDF preview with page-by-page navigation (
n/p/J/K) - File explorer integration — auto-previews when you open an image/PDF from Snacks explorer, neo-tree, oil.nvim, etc.
- Picker integrations — opt-in sixel previews inside the snacks.nvim picker, the mini.files preview pane, and telescope
- Dynamic sizing — detects your terminal's pixel dimensions and scales images to fit
- Render caching — in-memory cache with mtime-based invalidation
- Clean tab switching — sixel artifacts are cleared when you switch tabs, re-rendered when you return
:checkhealth— verifies all dependencies and terminal support
| Dependency | Required | Notes |
|---|---|---|
| Neovim >= 0.9 | Yes | 0.10+ recommended |
| Sixel-capable terminal | Yes | Windows Terminal 1.22+, WezTerm, foot, mlterm |
| ImageMagick 7+ | Yes | Must have sixel delegate (check with :checkhealth) |
| poppler-utils | For PDFs | Provides pdftoppm for fast PDF rasterization |
# Using scoop
scoop install imagemagick
scoop install poppler
# Or using winget
winget install ImageMagick.ImageMagick# Ubuntu/Debian
sudo apt install imagemagick poppler-utils
# macOS
brew install imagemagick poppler-- lua/plugins/sixel-preview.lua
return {
"truashamu/sixel-preview.nvim",
event = "VeryLazy",
cmd = { "SixelPreview", "SixelPreviewToggle", "SixelPreviewClose", "SixelPreviewPage" },
keys = {
{ "<leader>sp", "<cmd>SixelPreviewToggle<cr>", desc = "Toggle sixel preview" },
{ "<leader>sP", "<cmd>SixelPreviewClose<cr>", desc = "Close sixel preview" },
},
opts = {},
}Clone into your Neovim packages directory:
git clone https://github.com/truashamu/sixel-preview.nvim \
~/.local/share/nvim/site/pack/plugins/start/sixel-preview.nvim| Command | Description |
|---|---|
:SixelPreview [file] |
Preview a file (defaults to current buffer's file) |
:SixelPreviewToggle |
Toggle preview for current file |
:SixelPreviewClose |
Close the preview tab |
:SixelPreviewPage 3 |
Jump to a specific PDF page |
:SixelClearCache |
Clear the render cache |
When previewing a PDF, these buffer-local keybindings are active:
| Key | Action |
|---|---|
n / J |
Next page |
p / K |
Previous page |
q |
Close preview |
When auto_preview is enabled (the default), opening any supported file from a file explorer will automatically render it as sixel. Works out of the box with:
- Snacks explorer
- neo-tree
- oil.nvim
- Any plugin that triggers
BufReadCmd
Some plugins draw previews in their own scratch windows instead of loading the
file through BufReadCmd. Opt-in hooks are available for those:
require("sixel-preview").setup({
integrations = {
snacks_picker = true, -- snacks.nvim picker: image/PDF previews render as sixel
mini_files = true, -- mini.files: preview pane renders images/PDFs as sixel
telescope = true, -- telescope: default buffer previewer renders as sixel
},
})All integrations are fully optional: they default to off, their code is only loaded when enabled, and a missing target plugin just logs a warning.
- snacks_picker wraps the picker's default
filepreviewer and re-draws the image after snacks' own repaints (sixel pixels live in the terminal's graphics layer, so any window repaint wipes them). - mini_files requires
windows.preview = truein mini.files' own setup. - telescope routes telescope's default
buffer_previewer_makerthrough the sixel previewer, regardless of whether telescope's setup runs before or after this plugin's. A user-supplied maker in telescope's setup wins.
For finer control of telescope you can skip the flag and wire it manually - globally or per picker:
require("telescope").setup({
defaults = {
buffer_previewer_maker = require("sixel-preview.telescope").previewer_maker,
},
})
require("telescope.builtin").find_files({
previewer = require("sixel-preview.telescope").previewer(),
})These are the defaults — you only need to set what you want to change:
require("sixel-preview").setup({
-- Conversion backends
converters = {
image = "magick", -- "magick" (ImageMagick) or "chafa"
pdf = "pdftoppm", -- "pdftoppm" (poppler) or "magick"
},
-- Sixel output sizing (used as fallback when dynamic detection fails)
sixel = {
max_width = 800,
max_height = 600,
background = "none", -- "none", "black", "white"
cell_size = { 8, 16 }, -- fallback { width, height } in pixels per cell
},
-- PDF-specific
pdf = {
page = 1, -- default starting page
dpi = 150, -- rasterization resolution
},
-- Auto-preview when opening supported files
auto_preview = true,
-- Opt-in picker/explorer integrations
integrations = {
snacks_picker = false, -- wrap the snacks.nvim picker `file` previewer
mini_files = false, -- render the mini.files explorer preview pane
telescope = false, -- route telescope's default buffer previewer
},
-- Tab behavior
tab = {
close_on_leave = false, -- close preview tab when switching away
reuse = true, -- reuse existing preview tab
title = "Preview", -- tab title prefix
},
-- Supported file types
filetypes = {
image = { "png", "jpg", "jpeg", "gif", "bmp", "webp", "tiff", "ico", "svg" },
pdf = { "pdf" },
},
-- Binary overrides (if not on PATH)
bin = {
magick = "magick",
pdftoppm = "pdftoppm",
chafa = "chafa",
},
})Run :checkhealth sixel-preview to verify your setup:
sixel-preview.nvim
- OK Neovim >= 0.9
- OK Running inside Windows Terminal (WT_SESSION detected)
- OK ImageMagick found: ImageMagick 7.1.2-Q16-HDRI
- OK ImageMagick has sixel support
- OK pdftoppm found (poppler-utils)
- File detection — extension mapped to converter type (image or PDF)
- Conversion — ImageMagick converts to sixel format, writing to a temp file
- Display — raw sixel escape sequences sent to the terminal via
nvim_chan_send - Positioning — ANSI cursor positioning places the image inside the correct Neovim window
- Caching — rendered sixel data cached in memory, keyed on filepath + mtime + dimensions
For PDFs: pdftoppm rasterizes a page to PNG → ImageMagick converts to sixel.
On Windows, the plugin detects terminal pixel dimensions via the Win32 GetForegroundWindow + GetClientRect API (through LuaJIT FFI). On Unix, it uses the standard TIOCGWINSZ ioctl. This means images and PDFs scale properly to your window size — no hardcoded dimensions.

