Updated March 2026

Ghostty Best Practices

A comprehensive guide for macOS users running tmux + vim/neovim. Conflict-free keybindings, true color, undercurl, and shell integration.

👻 Ghostty 🪟 tmux 📝 vim / neovim 🍎 macOS

01 Configuration

Ghostty ships with sensible defaults — zero config required. Customise in ~/.config/ghostty/config.ghostty.

Useful commands

# Reload config at runtime
Cmd+Shift+,

# View all defaults with inline docs
ghostty +show-config --default --docs | less

# List available fonts and themes
ghostty +list-fonts
ghostty +list-themes

Recommended base config

# ~/.config/ghostty/config.ghostty

# ── Font ──
font-family = JetBrains Mono
font-size = 14
font-thicken = true          # macOS retina thickening

# ── Theme (auto light/dark switching) ──
theme = light:catppuccin-latte,dark:catppuccin-mocha

# ── Window ──
window-padding-x = 8
window-padding-y = 4
window-save-state = always
background-opacity = 0.97
background-blur = 20

# ── Cursor ──
cursor-style = block
cursor-style-blink = false

# ── Clipboard ──
clipboard-read = allow
clipboard-write = allow
clipboard-trim-trailing-spaces = true
clipboard-paste-protection = true
copy-on-select = false       # let tmux handle selection

# ── Rendering ──
window-vsync = true
window-colorspace = display-p3

# ── Misc ──
mouse-hide-while-typing = true
shell-integration = detectconfig.ghostty

Modular config

Split large configs across files for maintainability:

config-file = themes/current.ghostty
config-file = keybinds.ghostty
config-file = ?local.ghostty   # ? = optional, won't error if missing
💡 Popular font alternatives: Berkeley Mono, Iosevka, MonoLisa, BlexMono Nerd Font Mono. Disable ligatures with font-feature = -calt and font-feature = -liga.

02 Keybinding Strategy

The golden rule: each layer owns a modifier namespace. No conflicts.

Ghostty Cmd Cmd+Shift
tmux Ctrl-b prefix
vim Ctrl-* <Leader>
⚠️ On macOS, Ghostty should exclusively use Cmd combos. Leave Ctrl-* entirely for tmux and vim. This prevents every keybinding conflict.

Recommended Ghostty keybinds

# ── Tabs ──
keybind = cmd+t=new_tab
keybind = cmd+w=close_surface
keybind = cmd+shift+left_bracket=previous_tab
keybind = cmd+shift+right_bracket=next_tab
keybind = cmd+1=goto_tab:1
keybind = cmd+2=goto_tab:2
keybind = cmd+3=goto_tab:3

# ── Font Size ──
keybind = cmd+equal=increase_font_size:1
keybind = cmd+minus=decrease_font_size:1
keybind = cmd+zero=reset_font_size

# ── Utility ──
keybind = cmd+k=clear_screen
keybind = cmd+up=scroll_to_top
keybind = cmd+down=scroll_to_bottom
keybind = cmd+shift+comma=reload_configkeybinds.ghostty

Key tables (Vim-like sequences)

Ghostty supports key-table chords for complex actions without stealing modifiers:

keybind = cmd+k>cmd+t=toggle_tab_overview

View all default bindings: ghostty +list-keybinds --default

03 tmux Integration

True color, undercurl, clipboard passthrough, and zero escape delay.

tmux.conf essentials

# Use 256 colors and true color
set -g default-terminal "tmux-256color"

# Enable true color (RGB) passthrough for Ghostty
set -ag terminal-overrides ",xterm-ghostty:RGB"

# Enable undercurl
set -ag terminal-overrides ",xterm-ghostty:Smulx=\E[4::%p1%dm"

# Enable colored underlines
set -ag terminal-overrides ",xterm-ghostty:Setulc=\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m"

# Focus events (needed for vim autoread, gitsigns, etc.)
set -g focus-events on

# Mouse support
set -g mouse on

# Generous scrollback
set -g history-limit 50000

# CRITICAL: Zero escape delay for instant vim mode switching
set -sg escape-time 0

# OSC 52 clipboard (system clipboard through tmux)
set -g set-clipboard ontmux.conf
🚨 escape-time 0 is non-negotiable for vim users. The default 500ms delay makes Esc feel laggy and breaks Esc-based sequences.

Remote server terminfo

When SSHing to a host without xterm-ghostty terminfo:

MethodHow
Copy terminfo infocmp -x xterm-ghostty | ssh HOST -- tic -x -
SSH config fallback (OpenSSH 8.7+) SetEnv TERM=xterm-256color in ~/.ssh/config
Shell integration (automatic) shell-integration-features = ssh-terminfo,ssh-env
ℹ️ Falling back to xterm-256color loses Ghostty-specific features like colored/styled underlines. Copy the terminfo when possible.

04 vim / neovim Integration

True color, cursor shapes, undercurl, and the Kitty keyboard protocol.

True color (24-bit)

-- init.lua (neovim)
vim.opt.termguicolors = trueinit.lua

For classic vim (usually unnecessary with xterm-ghostty):

set termguicolors
let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"
let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum".vimrc

Cursor shape changes

Ghostty supports DECSCUSR. Neovim handles this automatically. For vim:

let &t_SI = "\e[6 q"   " Insert: bar
let &t_EI = "\e[2 q"   " Normal: block
let &t_SR = "\e[4 q"   " Replace: underline

Undercurl for diagnostics

-- Neovim LSP diagnostics with undercurl
vim.diagnostic.config({
  underline = true,
  virtual_text = false,
  signs = true,
})

vim.cmd([[
  hi DiagnosticUnderlineError gui=undercurl guisp=Red
  hi DiagnosticUnderlineWarn  gui=undercurl guisp=Orange
  hi DiagnosticUnderlineInfo  gui=undercurl guisp=LightBlue
  hi SpellBad                 gui=undercurl guisp=Red
]])init.lua
💡 Undercurl through tmux requires the Smulx terminal override from the tmux section above.

Kitty keyboard protocol

Both Ghostty and Neovim support the Kitty keyboard protocol — proper distinction between Ctrl+I and Tab, correct Ctrl+Shift combos, and better modifier handling. No configuration needed; they negotiate automatically.

05 Performance Tuning

GPU-accelerated by default. Minimal tuning needed.

Rendering
window-vsync = true
window-colorspace = display-p3

Keep vsync on — disabling it can trigger kernel panics on macOS 14.4+ with external displays.

Scrollback
scrollback-limit = 10000000

Allocated lazily — generous limits have no upfront memory cost.

⚠️ Custom shaders can cause 95%+ GPU utilisation. Background images are duplicated in VRAM per terminal surface. Use sparingly.

06 Shell Integration

Automatic for zsh, bash (Homebrew), fish, and elvish.

FeatureDescription
Smart closeNo confirmation when cursor is at shell prompt
Directory inheritanceNew tabs/splits inherit the working directory
Prompt redrawComplex prompts resize correctly
Command output selectCmd+triple-click selects entire command output
Cursor at promptBar cursor at prompt, block in applications
Prompt navigationjump_to_prompt scrolls between prompts
Click-to-moveOption+click moves cursor at prompt
sudo wrappingPreserves terminfo through sudo
SSH wrappingTransmits terminfo to remote hosts automatically
NotificationsAlert when long-running commands finish
shell-integration = detect
shell-integration-features = cursor,sudo,title,ssh-terminfo,ssh-env

# Notify on long-running command completion (when unfocused)
notify-on-command-finish = unfocused
notify-on-command-finish-after = 5000config.ghostty
⚠️ macOS ships /bin/bash v3.2, which is too old for automatic shell integration. Use brew install bash or source manually from ${GHOSTTY_RESOURCES_DIR}/shell-integration/bash/ghostty.bash.

07 Ghostty Splits vs tmux Panes

When to use native splits vs tmux — and the recommended approach.

Ghostty Native Splits

  • GPU-accelerated rendering
  • Native macOS feel with Cmd keys
  • No prefix delay
  • Independent scrollback per split
  • Zoom toggle

Lost when Ghostty closes. No detach/reattach. No remote session survival.

tmux Panes

  • Session persistence across restarts
  • Survives SSH disconnects
  • Rich layout scripting
  • Terminal-agnostic
  • Fully programmable

Prefix key adds minor latency. Requires terminal-overrides config.

💡
Recommended for tmux users: Use tmux for all pane management. Use Ghostty tabs only for separate project contexts. Unbind Ghostty split keys:
keybind = cmd+d=unbind
keybind = cmd+shift+d=unbind

08 Troubleshooting

Common issues and their fixes for the tmux + vim stack.

IssueFix
Escape delay in vim through tmux set -sg escape-time 0 in tmux.conf
"missing or unsuitable terminal: xterm-ghostty" on SSH Copy terminfo or set TERM=xterm-256color
True color not working in tmux Add terminal-overrides ",xterm-ghostty:RGB"
Undercurl shows as plain underline in tmux Add Smulx / Setulc terminal overrides
Kernel panics with vsync off + external displays Keep window-vsync = true
Copy/paste conflicts with tmux copy-on-select = false in Ghostty, set-clipboard on in tmux
macOS /bin/bash too old for shell integration brew install bash
Cmd+K not clearing properly Add explicit keybind = cmd+k=clear_screen

09 References

Official docs, config references, and community resources.