From configuring-ghostty-vibe-stack
Configures Ghostty-based terminal AI coding environment on macOS Apple Silicon with Fish shell, yazi, lazygit, Neovim/LazyVim, fzf, zoxide, atuin, and CJK fonts. For setup, configuration, and troubleshooting terminal tools.
npx claudepluginhub psylch/ghostty-vibe-coding-stack --plugin configuring-ghostty-vibe-stackThis skill uses the workspace's default tool permissions.
**Match user's language**: Respond in the same language the user uses.
Optimizes terminal for Claude Code with Ghostty config, statusline for context/git info, macOS voice dictation tips, tab naming, and tmux per git worktree.
Emulates terminal using libghostty-vt library: parses VT sequences for C0 controls, cursor movement/positioning, erase/display/line, SGR, OSC titles/hyperlinks. Includes tmux+zsh+fzf+ripgrep.
Guides macOS users through Lima VM setup for isolated dev environments, configuring name, resources, shared dirs, git, languages (Node.js, Go, Rust, Python), tools, AI agents, and ports.
Share bugs, ideas, or general feedback.
Match user's language: Respond in the same language the user uses.
A complete terminal-based AI coding environment for macOS (Apple Silicon). Replaces heavy IDEs with lightweight, composable tools for Claude Code / AI-assisted development.
Follow these steps in order. Skip steps where the tool is already installed.
Copy this checklist and track progress:
Setup Progress:
- [ ] Step 1: Pre-flight checks
- [ ] Step 2: Install Ghostty
- [ ] Step 3: Install CLI tools
- [ ] Step 4: Install fonts
- [ ] Step 5: Configure Ghostty
- [ ] Step 6: Configure Fish shell
- [ ] Step 7: Install Fish plugins
- [ ] Step 8: Configure lazygit
- [ ] Step 9: Configure yazi
- [ ] Step 10: Install Neovim + LazyVim
- [ ] Step 11: Set Ghostty as default terminal
- [ ] Step 12: Validate and verify
Verify prerequisites before starting:
# Check macOS and architecture
uname -m # expect: arm64
sw_vers --productVersion # expect: 13.0+
# Check Homebrew
brew --version || echo "Homebrew not installed — install from https://brew.sh"
If Homebrew is missing, install it:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Check what is already installed to skip redundant steps:
for cmd in ghostty fish yazi lazygit nvim fzf zoxide atuin fd rg bat delta; do
printf "%-10s: " "$cmd"
which $cmd 2>/dev/null || echo "not installed"
done
Use this table to resolve any missing items:
| Check | Fix |
|---|---|
| Homebrew not installed | Run the install script above |
ghostty not found | Step 2: brew install --cask ghostty |
| Any CLI tool not found | Step 3: brew install <tool> (all tools installed together) |
| Architecture not arm64 | This skill targets Apple Silicon; Intel Macs may have compatibility issues with some tools |
Check if Ghostty is already installed:
ls /Applications/Ghostty.app 2>/dev/null && echo "Ghostty installed" || echo "Not installed"
If not installed:
brew install --cask ghostty
Install all tools in one command (already-installed tools are skipped automatically):
brew install fish yazi lazygit neovim fzf zoxide atuin fd ripgrep bat git-delta
Ask the user which font setup they prefer before installing:
Option A: CJK-optimized (recommended for Chinese/Japanese/Korean users)
brew install --cask font-maple-mono-nf-cn font-sarasa-gothic font-jetbrains-mono-nerd-font
Option B: Latin-only (English-primary users)
brew install --cask font-jetbrains-mono-nerd-font
Read the complete config template from references/ghostty-config.md.
Before writing, ask the user about preferences:
ghostty +list-themes to show options. Popular: Monokai Vivid, Rose Pine, TokyoNight Storm, Catppuccin MochaCheck if config already exists before writing:
mkdir -p ~/.config/ghostty
ls ~/.config/ghostty/config 2>/dev/null && echo "Config exists" || echo "No config"
If config exists: show current content, ask the user:
cp ~/.config/ghostty/config ~/.config/ghostty/config.backup.$(date +%s) then write new configAfter writing, ALWAYS validate:
ghostty +validate-config
If validation shows theme errors, the theme name likely needs exact casing. Check with ghostty +list-themes | grep -i <name>.
Read the complete config template from references/fish-config.md.
Ask the user if they want to register Fish as a login shell. Explain this means:
chsh as a login shell optionsudo to modify /etc/shellschsh -s $(which fish) laterIf the user agrees, register Fish:
grep -q "$(which fish)" /etc/shells || echo "$(which fish)" | sudo tee -a /etc/shells
Do NOT run chsh automatically. Only mention it as an optional next step if the user asks to make Fish their default shell.
Check if config already exists before writing:
mkdir -p ~/.config/fish/{completions,conf.d,functions}
ls ~/.config/fish/config.fish 2>/dev/null && echo "Config exists" || echo "No config"
If config exists: show current content, ask the user:
cp ~/.config/fish/config.fish ~/.config/fish/config.fish.backup.$(date +%s) then write new configfzf --fish | source, zoxide init fish | source, atuin init fish | source) or aliases, grep for them in the existing file to avoid duplicates.After writing the config, validate Fish can parse it:
fish -n ~/.config/fish/config.fish && echo "Fish config syntax OK" || echo "Fish config has syntax errors"
If syntax errors are found, show the error output and fix the config before proceeding.
Import existing shell history into atuin:
fish -c "atuin import auto"
Check if Fisher (plugin manager) is installed:
fish -c "type fisher" 2>/dev/null || fish -c "curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher"
Install Tide prompt:
fish -c "fisher install IlanCosman/tide@v6"
Read the complete config template from references/lazygit-config.md.
The reference includes color themes for Monokai, TokyoNight, and Rose Pine. Match the lazygit theme to whichever Ghostty theme the user chose in Step 5.
Check if config already exists before writing:
mkdir -p ~/.config/lazygit
ls ~/.config/lazygit/config.yml 2>/dev/null && echo "Config exists" || echo "No config"
If config exists: show current content, ask the user:
cp ~/.config/lazygit/config.yml ~/.config/lazygit/config.yml.backup.$(date +%s) then write new configAfter writing, validate the YAML is parseable by lazygit:
lazygit -c ~/.config/lazygit/config.yml --version && echo "lazygit config OK" || echo "lazygit config may have issues"
If lazygit is not yet available, validate YAML syntax with:
python3 -c "import yaml; yaml.safe_load(open('$HOME/.config/lazygit/config.yml'))" && echo "YAML syntax OK" || echo "YAML syntax error"
Read the complete config template from references/yazi-config.md.
Check if config already exists before writing:
mkdir -p ~/.config/yazi
ls ~/.config/yazi/yazi.toml 2>/dev/null && echo "Config exists" || echo "No config"
If config exists: show current content, ask the user:
cp ~/.config/yazi/yazi.toml ~/.config/yazi/yazi.toml.backup.$(date +%s) then write new configAfter writing, validate the TOML is parseable:
python3 -c "import tomllib; tomllib.load(open('$HOME/.config/yazi/yazi.toml', 'rb'))" && echo "yazi config OK" || echo "TOML syntax error"
Check if nvim config already exists:
ls ~/.config/nvim/init.lua 2>/dev/null && echo "Nvim config exists" || echo "No config"
If config exists, ask the user:
cp -r ~/.config/nvim ~/.config/nvim.backup.$(date +%s) then clone freshIf no existing config (or user chose A), clone to a temp directory first so a failed clone does not destroy the existing config:
NVIM_TMP=$(mktemp -d)
git clone https://github.com/LazyVim/starter "$NVIM_TMP/nvim" && rm -rf "$NVIM_TMP/nvim/.git"
Only replace the config after a successful clone:
rm -rf ~/.config/nvim
mv "$NVIM_TMP/nvim" ~/.config/nvim
rm -rf "$NVIM_TMP"
If the clone fails, inform the user that their existing config (or backup) is untouched and suggest retrying when network is available.
Tell the user: first time opening nvim, LazyVim auto-installs all plugins — wait about 30 seconds.
Ask the user if they want Ghostty to replace their current default terminal in Finder's "Open in Terminal".
If yes, read the Swift helper from references/set-default-terminal.md and run it.
Run final verification:
echo "=== Tool Versions ==="
for cmd in fish yazi lazygit nvim fzf zoxide atuin fd rg bat delta; do
printf "%-10s: " "$cmd"
$cmd --version 2>&1 | head -1
done
echo ""
echo "=== Ghostty Config ==="
ghostty +validate-config 2>&1 || echo "Config OK (no output = no errors)"
echo ""
echo "=== Fish Shell ==="
fish -c "echo Fish is working"
Present the user with a summary of what was installed and configured, plus the quick reference below.
| Alias | Command |
|---|---|
y | yazi (file manager) |
yy | yazi with cd-on-exit |
lg | lazygit |
v | nvim |
cc | claude |
z <keyword> | zoxide smart cd |
| Ghostty Shortcut | Action |
|---|---|
Cmd+D | Vertical split |
Cmd+Shift+D | Horizontal split |
Cmd+Alt+Arrow | Navigate splits |
Ctrl+` | Quick Terminal (global) |
| Fish Key | Action |
|---|---|
Tab | Accept autosuggestion |
Alt+Tab | Accept one word |
→ | Completion menu |
Ctrl+R | History search (atuin) |
If new config breaks something, open Terminal.app (macOS built-in, always available) and run the appropriate fix:
| Broken | Fix |
|---|---|
| Ghostty won't launch or renders wrong | mv ~/.config/ghostty/config ~/.config/ghostty/config.broken — Ghostty uses defaults on next launch |
| Fish shell broken on startup | mv ~/.config/fish/config.fish ~/.config/fish/config.fish.broken — Fish loads without custom config |
| Want to revert Fish as login shell | chsh -s /bin/zsh |
| Want to remove Fish from /etc/shells | `sudo sed -i '' '|/fish$ |
| lazygit or yazi broken | Delete the config file (~/.config/lazygit/config.yml or ~/.config/yazi/yazi.toml) — tool reverts to defaults |
| Neovim/LazyVim broken | rm -rf ~/.config/nvim — if you have a backup: cp -r ~/.config/nvim.backup.<timestamp> ~/.config/nvim |
Any config with .backup.<timestamp> | cp <file>.backup.<timestamp> <file> to restore the backed-up version |
Theme names require exact casing with spaces:
rose-pine, tokyo-nightRose Pine, TokyoNight Stormghostty +list-themesghostty +validate-configCmd+V does not paste images into Claude Code (Ghostty bug, Discussion #10117):
Ctrl+V instead, or drag-and-drop image filesFish key binding syntax differs from Zsh:
bind -k right complete (-k is zsh syntax)bind right completebind \e\[C completeChinese text too large or misaligned:
font-family entryadjust-cell-height = 20%List available fonts: ghostty +list-fonts
List available themes: ghostty +list-themes