LWN.net needs you!Without subscribers, LWN would simply not exist. Please consider signing up for a subscription and helping to keep LWN publishing.
Kitty is a terminal emulator that runs on Linux, macOS, and the BSDs, which is notable for its speed and features such as image support and advanced font handling. It is under active development; a recent major release adds a new level of mouse support. Here, we will look at some of those features and show how the program can also be used as platform for text-based applications. Kitty is free software, released under the GPLv3.
Features
Kitty is a GPU-based terminal emulator. As with several other currently popular terminal emulators, use of the GPU provides it with enough bandwidth to dump megabytes of text onto the screen in an instant. This is a welcome virtue when accidentally displaying a huge file using cat, but the GPU also enables smooth exploration of the scrollback buffer. Kitty is designed to have low latency, which refers to the time between striking a key and the appearance of the corresponding character on the screen. This is a property that users are often not consciously aware of, but that has an important effect on the satisfaction and well-being of the terminal jockey.
Kovid Goyal created kitty when he became dissatisfied with the speed of the terminal emulator he was using [YouTube interview video] and decided to make a faster one. He then began to add features, starting with colored underlines, that he wanted but existing programs didn't support.
Kitty is thoroughly customizable through a configuration file. The user can define keyboard shortcuts or mouse actions for dozens of commands. The options go far beyond the usual appearance and keyboard shortcut settings; for example, there are several parameters exposed for performance tuning. In recent kitty versions, changes to the settings go into effect immediately upon saving the configuration file.
Font handling in kitty is flexible—as long as "fonts" does not include bitmap fonts, which kitty does not and will not support because they do not scale arbitrarily. Kitty can use any monospace TrueType or OpenType font and change its size on the fly with a keyboard shortcut.
Ligatures are supported (but, thankfully, can be disabled), as are alternative glyph shapes in OpenType and variable fonts. Separate fonts for normal, italic, and boldfaced text can be defined. In the configuration file, the user can also tell kitty which font to use for which Unicode codepoints, or range of codepoints. This is useful if, for example, a favorite coding font doesn't have good Unicode coverage, or if different fonts do a better job at rendering certain glyphs. There are parameters available to adjust font metrics and things like the position and thickness of underlines and strikethroughs; even how kitty composites text onto the background color can be adjusted.
If the user permits,
kitty
can override the colors chosen by an application
running in the terminal when they would lead to insufficient contrast between
foreground and background. I have this turned on, as it protects me
against, for example, carelessly defining too similar foreground and
background colors for a Vim highlight. As the documentation points
out: "Terminal aficionados spend all day staring at text, [so] getting
text rendering just right is very important.
"
Kittens
Kitty comes bundled with a handful of auxiliary programs called "kittens" that provide extra functionality and customization to the program. They are invoked with keyboard shortcuts or by executing the kitten command with an argument to select the desired kitten in the shell. The kitten command with no argument will display the list of available kittens. For brief documentation of any of them, a -h flag is provided; for example, kitten ssh -h for a guide to using the ssh kitten.
Kitty is designed to be extendable by the user. To this end kittens are implemented as external Python programs using an API that allows them to control kitty and gives them access to the text in a kitty window and in its scrollback buffer.
There are many kittens available; here I will mention some of the especially useful ones that come bundled with kitty. The ssh kitten wraps the system's ssh command to ensure that the remote connection plays well with kitty, mainly by transmitting the needed terminfo setting and enabling shell integration (more on that below) on the remote machine; it also brings other conveniences, such as reusing existing connections. There is a kitten that lists and previews any usable font installed. A theme picker allows interactive selection of a preset color theme from among far too many contributed options. The icat kitten uses the "terminal graphics protocol" (described below) to display an image file in any common format (including animated GIFs) directly in the terminal. Image files can be local or fetched with HTTP(S) or FTP; it will even work directly over SSH, as long as the remote machine has kitty installed.
The show-key kitten displays keycodes corresponding to key presses, similar to the xev program. A clipboard kitten enables copy and paste of various data types (e.g. images) over SSH. There is also a unicode input kitten for interactive searching and selecting Unicode characters, as can be seen in the screen shot below.
Kitty has a "hints mode" where any URL visible on the screen can be opened in the user's web browser by pressing a single key. It works like the popular Vimium browser extension, and uses a kitten under the hood. Remote control of kitty is provided by a kitten with many options allowing the user to send text to specific windows, change their properties, open and close windows and tabs, and more.
The kitty program features what the documentation calls "shell integration". This works for most popular shells such as Zsh, fish, and Bash, and third-party integrations are available for more exotic ones such as Nushell and Xonsh. Shell integration is a set of functions and shortcuts that make working at the command line more convenient. There are commands for opening the default editor with the contents of the scrollback buffer, the output of the most recent command, or the current command. Shell integration also supplies tab completion of kitty commands and various utility functions that are inserted into the shell environment, such as clone-in-kitty, which clones the current shell environment, including all environment variables, into a new window or tab. Another useful utility is edit-in-kitty, which enables editing remote files over SSH with the local editor.
New protocols
Kitty has created several new terminal protocols, implemented as sets of escape codes. Some of these protocols enable various kitty tricks, such as the terminal graphics protocol, which powers the icat command mentioned above. (Those familiar with the older sixel protocol may wonder why kitty didn't use that; the reason is that kitty's creator wanted to support a handful of features that are not supported by sixel graphics.) Additional kitty protocols improve on other legacy protocols, such as one that implements more flexible keyboard handling.
Other new protocols or protocol extensions implement colored and styled text underlines, copying of various types of data (images, text styles) to the clipboard, changing the shape of the mouse pointer, and mouse drag-and-drop of files to and from GUI file navigators. That feature is made possible by the enhanced mouse support that arrived with the latest major release.
Some of these protocols have been adopted by other projects, so, for example, users of Ghostty or Wezterm, along with several other terminal emulators, enjoy the benefit of kitty's terminal graphics protocol. It is also used by a long list of terminal-based applications, in addition to terminal emulators, and by plugins for editors. One such enhancement that I use with Neovim is the image component of the snacks plugin. It embeds graphics into Markdown buffers where it sees the Markdown syntax for inserting an image, or, optionally, displays them in popup windows. It also calls out to Typst and LaTeX (which, of course, need to be installed) to process math input and displays the result directly in the buffer. The plugin also understands Typst and LaTeX syntax for including images, and embeds those as well. Because Typst is so fast, the user gets realtime preview of the math when editing Typst documents.
Ι'll mention two final applications of kitty's terminal graphics protocol that I've found useful: both gnuplot and Julia can use it to embed their graphical output directly in their read-eval-print loops (REPLs), the former using a built-in "terminal", and the latter using the KittyTerminalImages Julia package. It can sometimes be useful to have, in the REPL, a record of plots alongside the commands that created them, an association that is lost when graphics are displayed in a separate window.
Interface builder
The kitty window can be split vertically or horizontally into any number of sub-windows, each with its own title, background color, and other properties. The resulting collection of component windows can be rearranged into a variety of layouts, and arbitrarily resized, similar to a tiling window manager such as dwm. The window arrangement can be saved as a "session" with a keyboard shortcut. The session information is saved in a text file that contains the layout details and also records what program each window was running at the time the session was created. These sessions can largely replace terminal multiplexers such as tmux.
In earlier kitty versions, arranging and resizing the windows in a session was done with the keyboard. While I generally prefer the keyboard to the mouse, this was not ideal. The new mouse handling in kitty v0.47.0 enables resizing and moving windows visually with a nicely thought-out interface that allows dragging window partitions and dragging and dropping windows to rearrange them. Session windows can even be dragged out of the session to become separate windows.
A session can loaded with the --session flag on the kitty command. The user can also load or switch sessions when using kitty with keyboard shortcuts. When a session is loaded, all of the programs that had been running in each window are started. Any shared SSH connections made with the ssh kitten mentioned above, which were active when the session was saved, will be reactivated.
An obvious use of kitty sessions is to define environments needed for various projects or tasks. A system administrator might want a session with several windows connected to different servers. A programming project could include a code editor, a REPL, and a window displaying documentation.
When sessions are combined with kitty's remote-control abilities they become the basis for simple text-user-interface (TUI) applications. To make such an application with kitty, it suffices to create the desired layout and save it as a session. The programs running in the component windows can handle user input and send and receive text and commands from each other in response. Considered this way, kitty becomes a kind of TUI construction kit.
Above is a screenshot from a simple image browser that I built using this machinery. When the user selects an image file from a list, it displays the image and some information about it. The list is filtered and displayed by fzf in one window, the image is displayed in another window with kitty's icat kitten, and the image information is displayed in a third window by processing the output from the exif command.
Kitty is generally available from distribution repositories, but for those who desire a release more recent than that, the installation instructions describe methods for binary installation and for building from source. Kitty's GitHub page shows over 400 contributors, with Goyal making the vast majority of commits. It's written in Python, C, and Go, with a smattering of a few other languages.
Conclusion
I decided to try out kitty a few years ago because I was intrigued by some of its features, such as advanced image display. It has since become indispensable. Kitty strives to be more than a terminal emulator; it provides a rich environment for textual human-computer interaction. But its panoply of features stay out of the way of the user who simply wants a fast terminal with good font support. They can be explored gradually, and incorporated into workflows as desired. I'm still discovering kitty features that make my life in the terminal more convenient.
Kitty does have at least one problem, which sometimes creates confusion: its name, which is shared with a combination networking client and terminal emulator for Windows.
Finally, because undoubtedly some readers are wondering: yes, you can play Doom in kitty.
| Index entries for this article | |
|---|---|
| GuestArticles | Phillips, Lee |