cat posts/2024-12-30-ghostty-and-my-terminal.md
Ghostty and my terminal
The terminal is the program I have open longest every day, by a wide margin. Since I moved most of my editing into Neovim in a terminal, it’s effectively my editor’s window too. And for years I’ve picked terminals the way most people pick a toothbrush: whatever was there, set up once, never thought about again. On the Mac that’s been iTerm2 for about a decade. On Windows it’s Windows Terminal. On Linux I mostly arrive over SSH, so the terminal is whatever’s on the machine I’m coming from.
On Thursday, Mitchell Hashimoto released Ghostty 1.0, and I’ve used nothing else on the Mac since.
What it is
Hashimoto co-founded HashiCorp, the company behind Terraform and Vagrant, and left it about a year ago. Ghostty started in 2022 as a side project, by his own account a way to learn Zig and to understand how terminals work, and it’s been in a private beta for a long time. His reflection post on release day says the beta ended up at about 5,000 people. It’s MIT licensed.
The design is a shared core, written in Zig, that does the actual terminal emulation, and a separate native app for each platform: Swift and AppKit on macOS, GTK on Linux. That’s the part that got my attention. Most fast terminals are fast and look the same everywhere, which on a Mac means they feel slightly foreign: their own tabs, their own settings windows, keyboard shortcuts that are almost right. Ghostty’s tabs are real macOS tabs, its splits behave like the rest of the system, and the settings are a text file. It renders on the GPU, through Metal on the Mac and OpenGL on Linux.
Is it faster than iTerm2? It feels faster, especially scrolling through a big log in less and anything with a lot of output. I didn’t benchmark it properly and I’m not going to pretend I can see the difference in input latency that people argue about on the forums. What I can tell you is that after four days, iTerm2 feels sluggish when I open it, which I’d never noticed before.
My config
The config file lives at ~/.config/ghostty/config, on both platforms, as plain key = value lines, and the defaults are good enough that you could run it with an empty file. This is everything I changed:
font-size = 14
theme = catppuccin-mocha
window-padding-x = 8
window-padding-y = 6
macos-option-as-alt = true
copy-on-select = clipboard
shell-integration-features = no-cursor
keybind = global:ctrl+grave_accent=toggle_quick_terminal
Some notes on that. The default font is JetBrains Mono, which is what I’d have picked anyway, so there’s no font line. Ghostty ships with hundreds of built-in themes, and ghostty +list-themes shows them with a preview. Catppuccin is the palette I use everywhere, including on the diagrams on this blog, so that was easy. The macos-option-as-alt line is for Neovim and the shell, which want Option to be Meta, not a key for typing é. Shell integration is on by default for zsh and bash, and it does useful things like knowing where each prompt starts so you can jump between them, but it also changes the cursor shape in the shell, which I turned off. And the last line is the quick terminal, a Ghostty window that drops down from the top of the screen on a global hotkey, which I’d been doing with an iTerm2 hotkey window for years.
If you want to see every option, ghostty +show-config --default --docs prints them all with their documentation. It’s a long read, and a better reference than most terminals’ websites. The config is in my dotfiles repo now, next to the Neovim config, so it’s on every Mac I use.
The thing that broke
SSH. Ghostty sets TERM to xterm-ghostty, and on any server that doesn’t have Ghostty’s terminfo entry installed, which is every server I have, programs that look up the terminal’s capabilities either complain about an unknown terminal or quietly fall back to something dumb. htop refused to start on one box. Neovim was fine, mostly.
The Ghostty docs cover this, with two fixes. You can copy the terminfo entry to each server you use, which is a one-line command and the proper fix. Or you can set TERM=xterm-256color for SSH sessions and lose a few features nobody on a server needs. I did the first on the two Linux boxes I use most, and set the fallback in my SSH config for everything else. I expect distributions will start shipping the entry eventually.
The missing platform
There’s no Windows version, and no sign of one soon. That’s the biggest practical gap for me, because I’m on a Windows laptop for part of most weeks, and the whole reason I moved to a terminal editor was to have the same setup on all three. Windows Terminal is good, honestly, and it’s not where my complaints were. But it does mean my terminal config now lives in two formats, which is one more than I wanted.
I didn’t expect to be changing terminals at 45, over a holiday week, for a few milliseconds I can’t measure. iTerm2 is still installed, for now.