Back Original

Ghostty 1.4.0

Ghostty 1.4.0 is a major release that includes large performance and memory improvements, a 100% complete Kitty graphics implementation including animation and relative placements (the first non-Kitty terminal to do so), SSH integration improvements, and hundreds more improvements and fixes across all platforms.

This release features 7 months of work with changes from 172 contributors over 2,889 commits. Thank you to all the contributors, maintainers, community moderators, translators, packagers, and users who each helped make this release possible.

These release notes are painstakingly and lovingly hand-crafted by human Ghostty maintainers, including the full changelog. They take a combined 16+ hours to write, so please enjoy. 🥰

Note: I requested CVEs for the above advisories weeks ago, but GitHub hasn't assigned them yet. If/when they're assigned, I will update the above with proper CVE numbers.

PRs: #12999 #13069 #13393 #14413 #14414

Ghostty 1.4 supports macOS 27 (Golden Gate). Most of the work was compatibility fixes:

Ghostty 1.4 remains fully compatible with prior macOS versions back to and including macOS 13 (Ventura). See the system requirements for more details.

Ghostty 1.3.1 works on macOS 27, but it has some of the visual issues listed above, such as the gray tab bar.

PRs: #13943 #13939 #13935 #13934 #13893 #13933 #13389 #13270 #13281

Ghostty now supports Kitty graphics animation and relative placements. These were the last major features of the Kitty graphics protocol that Ghostty didn't support.

Programs that display animated images with the Kitty protocol, such as an animated GIF shown with kitten icat, now animate in Ghostty instead of showing a single still frame. Frame transmission, composition, and playback control are all supported, and animations pause while the terminal isn't visible. Relative placements let a program position one image relative to another image's placement, so the child image moves along with its parent.

We also did a full conformance pass against the specification and Kitty itself, fixing dozens of behavioral differences. For example, images now scroll with text inside scroll regions (#4323 ), retransmitting an image ID replaces the old image (#6711 ), and invalid image data now gets an error response instead of silence, which could leave clients hanging. The full list is in the terminal capabilities section.

Kitty graphics are faster, too. Image payloads are now parsed in bulk with SIMD instead of one byte at a time, making large image transfers about 16x faster to parse in our benchmarks (64 MiB of image data, x86_64 Linux), and drawing images costs much less per frame.

Our Kitty graphics implementation now covers 100% of the published specification, making Ghostty (and libghostty) the first terminal to do this outside of Kitty itself.

PRs: #13264 #13473 #13240 #13245 #14130 #14137 #14138 #14017

Ghostty now transparently compresses scrollback that isn't visible, reducing the physical memory those pages use by 70% to 90% for typical text-heavy history. Compression only runs while the terminal is idle and pages are decompressed on demand when you scroll back or search, so it has no measurable impact on I/O throughput.

Thanks to compression, the default scrollback limit has been raised from 10 MB to 50 MB per terminal. On platforms that support compression, a full scrollback still generally uses less physical memory than the old 10 MB limit did.

Compression lowers resident (physical) memory, not virtual memory, so look at resident memory when measuring it. It is currently available on macOS and 64-bit Linux.

Beyond scrollback, memory usage is lower in many places:

PRs: #13209 #13220 #13226 #13227 #13537 #13827 #13587 #14011 #13722 #14035 #12760

There are performance improvements across the board in Ghostty 1.4 that yield significant gains compared to prior Ghostty versions.

The biggest win came from a surprising discovery: on macOS, the kernel caps every read from a pty at about 1 KiB no matter how large the read buffer is. Previously, Ghostty processed each read as it arrived, so per-read overhead was paid every kilobyte, and the program writing output sat blocked while we parsed. Ghostty now drains the pty on one thread while parsing on another, raising end-to-end I/O throughput by 25% to 55% on macOS (M4 Max, plain and Unicode text) over Ghostty 1.3.x.

VT processing itself is also much faster. In parser benchmarks, plain ASCII text went from 128 MB/s to 725 MB/s (5.7x), CJK text got 3.4x faster, and a 2.6 GB dataset of real-world terminal recordings from asciinema is processed about 25% faster. Together, these changes took cat-ing a 150 MB text file on macOS from 1.5 seconds to 566 milliseconds.

Other notable improvements:

PRs: #14052 #14269

The GTK app has a new rendering pipeline. It no longer uses GtkGLArea. Instead, the renderer draws with EGL on its own thread, exports each frame as a DMABUF, and hands it to GTK to display. Rendering is now triple-buffered, which should greatly reduce tearing, and no OpenGL calls run on the main thread anymore, which let us remove a number of workarounds.

The most visible result is crisp text under fractional scaling. Text and box-drawing characters are no longer blurry with fractional display scaling such as 125% or 150% (#1938 ). We fixed this once before, but it came back after upstream GTK changes. Ghostty now renders at the window's true fractional scale, so every rendered pixel maps to exactly one pixel on screen.

The new render surface needs a system EGL library (see Changes for Package Maintainers). On GPU drivers that can't export DMABUFs, Ghostty falls back to copying frames through the CPU, which is slower but works.

PRs: #13962 #13993 #13995 #13998 #14002 #14061

Ghostty now implements the Kitty clipboard protocol (OSC 5522) on both macOS and GTK. Ghostty 1.3 could parse the protocol but didn't implement it.

OSC 52 can only read and write plain text. The Kitty clipboard protocol lets programs running in the terminal read and write any kind of clipboard data, such as images or HTML, and lets them pick among the formats on the clipboard. Programs can also enable paste events (mode 5522), which tell the program what formats a paste contains so it can read the one it wants. This is how a terminal program can accept a pasted image, for example.

Clipboard access follows the existing clipboard-read and clipboard-write configurations. By default, reads prompt for permission and writes are allowed. The permission prompt shows a preview of the clipboard contents, including images. Programs that send a password can have your answer remembered for the rest of that terminal session. A new clipboard-write-limit-bytes configuration limits the size of a single write (default 64 MiB). A write over the limit fails and leaves the clipboard untouched.

PRs: #10423 #13706

You can now rearrange splits on GTK by dragging them, matching the macOS feature introduced in Ghostty 1.3. When a tab has two or more splits, each split shows a drag handle at the top. Grab the handle and drop the split onto any other split, including splits in other tabs and windows. An overlay shows which side of the target split it will land on. The terminal contents, working directory, and running processes all move with it.

A new drag-handle configuration controls when drag handles are shown on both macOS and GTK: auto (default), always, or never. With never, splits can't be rearranged with the mouse. Hiding the handles was a common request from users who found them in the way.

On GTK, splits can only be dropped onto other splits. Dragging a split out to create a new tab or window is macOS-only.

PRs: #14454 #13494 #14483 #14538 #14673 #14375 #14144

Ghostty 1.4 includes dozens of improvements to core terminal emulation. We now run esctest, Thomas Dickey's terminal conformance suite, against Ghostty's terminal core in CI. Alongside that, we fixed many differences from xterm in cursor movement within margins, tab stops, character sets, mode reports, and more. You can find the full list of related changes in the terminal capabilities section.

Ghostty also supports several new sequences, including soft terminal reset (DECSTR), extended cursor position reports (DECXCPR), backarrow key mode (DECBKM), and screen size reports in characters (CSI 19 t). Programs can also now ask whether the terminal is visible using visibility reports (mode 2033), so they can stop rendering while hidden.

Keyboard encoding also matches xterm more closely, with fixes for modifyOtherKeys mode 2 and legacy Alt-as-Escape encoding of non-ASCII keys.

Two new sequences are disabled by default because they can be abused by untrusted programs, including ones running on a remote machine:

# Allow programs to resize the window (CSI 8 t)
vt-window-resize-allowed = true

# Allow programs to request screen checksums (DECRQCRA)
vt-xt-checksum-report = true

PRs: #12582 #12814 #13533 #13844 #14472 #14854

Ghostty 1.2 introduced SSH shell integration features as a work in progress. In Ghostty 1.4, they're backed by a new ghostty +ssh CLI action: a drop-in ssh wrapper that prepares the remote session for Ghostty and then runs the real ssh with your arguments forwarded unchanged.

ghostty +ssh user@example.com


alias ssh='ghostty +ssh --'

Before connecting, +ssh installs Ghostty's terminfo on the remote host so the proper xterm-ghostty TERM value can be used, and forwards COLORTERM, TERM_PROGRAM, and TERM_PROGRAM_VERSION. If the terminfo install fails (for example, tic isn't available on the remote), it falls back to TERM=xterm-256color. Flags such as --terminfo=false, --forward-env=false, and --verbose control each step.

The ssh-env and ssh-terminfo shell integration features (still opt-in) now call +ssh too. Previously, each shell integration carried its own copy of this logic, which made up roughly a third of our shell integration scripts. Now bash, zsh, fish, elvish, and Nushell all behave identically, and you can get the same behavior from scripts or anywhere else by calling ghostty +ssh directly.

The terminfo install itself is also more reliable. Ghostty now always installs its own bundled terminfo rather than accepting whatever xterm-ghostty entry the remote already has, and it reinstalls automatically when a Ghostty update changes the terminfo. It also no longer needs infocmp or Ghostty's terminfo on the local machine. Installs are cached per host and port, so two machines behind one address no longer share a cache entry. And ssh-env no longer silently overrides SetEnv entries in your ~/.ssh/config (#11518 ).

The +ssh-cache command that manages this cache now takes positional destinations (ghostty +ssh-cache user@example.com) and has a new --prune=30d flag. See the breaking changes if you script against +ssh-cache.

macOS: The minimum required macOS version for Ghostty 1.4 remains unchanged (macOS 13 Ventura). Ghostty is now compatible with macOS 27.

GTK: Ghostty 1.4 requires GTK 4.18 and libadwaita 1.7, up from GTK 4.14 and libadwaita 1.5 in Ghostty 1.3. This aligns with our GTK/Adwaita version policy. Notably, Ubuntu 24.04 LTS doesn't meet this requirement. Systems with older GTK or Adwaita versions can work around this requirement by using an older version of Ghostty or the Flatpak package. #14330

OpenGL (GTK): The minimum required OpenGL version remains 4.3, but Ghostty now renders through EGL instead of GTK's OpenGL widget. This should be invisible for nearly everyone, but if Ghostty fails to start with an EGL error, please make sure your GPU driver provides a working EGL implementation.

We previously announced that Ghostty 1.4 would require macOS 14. Nothing forced our hand to do this in this release, so we kept macOS 13 support. We still plan to drop macOS 13 in a future release. Apple dropped security support for macOS 13 in the fall of 2025, so we recommend upgrading regardless.

The following behaviors have changed in 1.4.0:

The list below contains deprecations that remain compatible today through a compatibility layer, but may break in a future release if they are ignored:

There is no set timeline to remove these deprecations, but we recommend adapting to the new configurations sooner rather than later to avoid any possible disruptions in the future.

Ghostty 1.4 introduces full localization for the command palette and adds support for 4 new languages:

Localization is maintained by volunteer contributors. If you want to help localize Ghostty in your language, please open a discussion on the GitHub repo. Thank you to all the volunteers who contributed to Ghostty's localization!

As with 1.3, libghostty isn't directly part of the Ghostty 1.4 release. But a large part of the 1.4 development cycle went into libghostty, so here's an update.

Over the past 6 months, the C API for libghostty-vt has grown from a parser and a few encoders into a complete terminal emulator API, adopted by dozens of free and commercial terminal emulators used by millions of people. It's hard to quantify exactly, but the number of people using a libghostty-based terminal is confidently several times the number of people using the Ghostty GUI.

libghostty-vt now builds for macOS, Linux, Windows (MSVC and GNU), FreeBSD, Android, iOS, and WebAssembly, and CI continuously verifies every one of these targets. The goal is for libghostty-vt to be generally usable everywhere, within reason, so if you want more target support, let us know!

It's also easier to integrate libghostty-vt into existing build systems. There's CMake support, Nix packaging, an xcframework, and a source tarball, in addition to the existing pkg-config file. libghostty-vt no longer needs libc++, and it can build freestanding.

The API is still marked as a work in progress and broke compatibility several times during this cycle, so expect more breaking changes before a tagged release. The API documentation and the Zig, C, C++, Swift, and WebAssembly examples (now over 30) are kept up to date with main.

We're going to do a final pass over the C API, break ABI one more time, and then likely tag a libghostty 1.0 release very soon.

Ghostty is a non-profit project, fiscally sponsored by Hack Club. All of our finances are public on HCB, so you can see exactly where every dollar goes.

During the 1.4 cycle, we paid $41,820 to contributors under contract and spent about $1,260 on infrastructure such as website hosting.

I'm happy to share that we've now signed our first two 12-month contracts, which give contributors stable, long-term paid work on Ghostty and help ensure the ongoing stability and sustainability of the project:

If you'd like to support Ghostty, please visit our sponsorship page.

The primary focus of the roadmap continues to be libghostty functionality, stability, and portability. During the last release cycle, I said I aimed to tag a libghostty release. We haven't done that yet, but I'm confident we will do so before Ghostty 1.5.

libghostty is a project that continues to be the tide that lifts all boats. libghostty improvements tie directly to Ghostty GUI improvements as well as dozens of other large projects in the ecosystem. As more large projects adopt libghostty, libghostty tends to get more testing and attention, and this creates a cycle that yields the most gain for terminal emulators everywhere.

macOS and GTK builds of Ghostty have talented, capable maintainer teams that are continuing to improve them, so they're not neglected by any means! As a project, we've decided to drop any roadmap for Windows support in the Ghostty GUI. libghostty fully supports Windows (and we test it in CI), and the official stance now is that downstream projects should use that.

Our release cycle remains 6 months. This release was delayed by one month, but Ghostty 1.5 is planned for March 2027. libghostty will have a separate release cycle.