GHOSTTY(1)

๐ŸŒธ NAME ๐ŸŒธ

ghostty โ€” Ghostty terminal emulator. Yep bestie, this is the GHOSTTY(1) manual page, and we are officially in our terminal-emulator era ๐Ÿ’…โœจ


๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

Ghostty is a cross-platform, GPU-accelerated terminal emulator that aims to push the boundaries of what is possible with a terminal emulator by exposing modern, opt-in features that enable CLI tool developers to build more feature rich, interactive applications. No cap, thatโ€™s the whole mission ๐Ÿ’–

There are a number of excellent terminal emulator options that exist today. Ghosttyโ€™s unique goal is to have a platform for experimenting with modern, optional, non-standards-compliant features to enhance the capabilities of CLI applications. We aim to be the best in this category, and competitive in the rest. Periodt ๐Ÿ‘‘

While aiming for this ambitious goal, Ghostty is a fully standards compliant terminal emulator that aims to remain compatible with all existing shells and software. You can use this as a drop-in replacement for your existing terminal emulator. So yes, you can absolutely bring it to your current setup and it should slay ๐Ÿซถ


๐ŸŽ€ COMMAND LINE ACTIONS ๐ŸŽ€

Okay so these are the command line actions, aka the little + spells and -- flags you can run. Every single one is here, bestie โ€” no skipping, no summarizing, we keep the lore intact ๐ŸŒˆ

๐Ÿ’– --version

The version command is used to display information about Ghostty. Recognized as either +version or --version. Easy peasy ๐Ÿ’ซ

โœจ --help

The help command shows general help about Ghostty. Recognized as either -h, --help, or like other actions +help.

You can also specify --help or -h along with any action such as +list-themes to see help for a specific action. So if youโ€™re ever like โ€œwait what does this one do again?โ€, the help girlies have you covered ๐ŸŽ€

๐Ÿ”ค +list-fonts

The list-fonts command is used to list all the available fonts for Ghostty. This uses the exact same font discovery mechanism Ghostty uses to find fonts to use. Itโ€™s giving โ€œshow me the receipts, font editionโ€ ๐Ÿ’…

When executed with no arguments, this will list all available fonts, sorted by family name, then font name. If a family name is given with --family, the sorting will be disabled and the results instead will be shown in the same priority order Ghostty would use to pick a font.

Flags:

  • --bold โ€” Filter results to specific bold styles. It is not guaranteed that only those styles are returned. They are only prioritized.
  • --italic โ€” Filter results to specific italic styles. It is not guaranteed that only those styles are returned. They are only prioritized.
  • --style โ€” Filter results based on the style string advertised by a font. It is not guaranteed that only those styles are returned. They are only prioritized.
  • --family โ€” Filter results to a specific font family. The family handling is identical to the font-family set of Ghostty configuration values, so this can be used to debug why your desired font may not be loading. Very โ€œwhy is my font not loadingโ€ coded, but make it useful ๐Ÿ’–

โŒจ๏ธ +list-keybinds

The list-keybinds command is used to list all the available keybinds for Ghostty.

When executed without any arguments this will list the current keybinds loaded by the config file. If no config file is found or there arenโ€™t any changes to the keybinds it will print out the default ones configured for Ghostty. Lowkey perfect for when youโ€™re like โ€œwait, what did I bind to what?โ€ ๐Ÿ˜ญ

Flags:

  • --default โ€” will print out all the default keybinds
  • --docs โ€” currently does nothing, intended to print out documentation about the action associated with the keybinds
  • --plain โ€” will disable formatting and make the output more friendly for Unix tooling. This is default when not printing to a tty.

๐ŸŒˆ +list-themes

The list-themes command is used to preview or list all the available themes for Ghostty. Theme shopping is serious business, bestie ๐ŸŽ€

If this command is run from a TTY, a TUI preview of the themes will be shown. While in the preview, F1 will bring up a help screen and ESC will exit the preview. Other keys that can be used to navigate the preview are listed in the help screen. Very interactive, very cutesy, very demure ๐Ÿ’…

If this command is not run from a TTY, or the output is piped to another command, a plain list of theme names will be printed to the screen. A plain list can be forced using the --plain CLI flag.

Two different directories will be searched for themes.

The first directory is the themes subdirectory of your Ghostty configuration directory. This is $XDG_CONFIG_HOME/ghostty/themes or ~/.config/ghostty/themes.

The second directory is the themes subdirectory of the Ghostty resources directory. Ghostty ships with a multitude of themes that will be installed into this directory. On macOS, this directory is the Ghostty.app/Contents/Resources/ghostty/themes. On Linux, this directory is the share/ghostty/themes (wherever you installed the Ghostty โ€œshareโ€ directory). If youโ€™re running Ghostty from the source, this is the zig-out/share/ghostty/themes directory.

You can also set the GHOSTTY_RESOURCES_DIR environment variable to point to the resources directory. Environment variable girlies rise up ๐ŸŒฑ

Flags:

  • --path โ€” Show the full path to the theme.
  • --plain โ€” Force a plain listing of themes.
  • --color โ€” Specify the color scheme of the themes included in the list. This can be dark, light, or all. The default is all.

๐ŸŽจ +list-colors

The list-colors command is used to list all the named RGB colors in Ghostty. Itโ€™s giving color palette show-and-tell ๐Ÿ’–

Flags:

  • --plain โ€” will disable formatting and make the output more friendly for Unix tooling. This is default when not printing to a tty.

๐Ÿงš +list-actions

The list-actions command is used to list all the available keybind actions for Ghostty. These are distinct from the CLI Actions which can be listed via +help. Important distinction, bestie โ€” donโ€™t mix the two up ๐Ÿ‘‘

Flags:

  • --docs โ€” will print out the documentation for each action.

๐Ÿ” +ssh

Wrap ssh to automatically configure Ghostty terminal integration on remote hosts. Remote-host glow-up, no cap ๐Ÿซถ

Any arguments that arenโ€™t recognized as +ssh flags are passed to the real ssh binary unchanged. You can use -- as an explicit disambiguator if needed, though itโ€™s almost never required: ssh has no long flags, and +ssh defines no short flags, so thereโ€™s nothing to collide. Convenient? Extremely โœจ

This is typically called via Ghosttyโ€™s shell integration. When shell-integration-features includes ssh-env or ssh-terminfo, each shell defines an ssh function that runs:

ghostty +ssh <flags> -- "$@"

You can also run ghostty +ssh directly, or alias it yourself (e.g. alias ssh='ghostty +ssh --') if you prefer not to use the shell integration.

Before it starts ssh, +ssh can do two pieces of setup. Both are on by default, and each has its own flag:

  1. Forward Ghosttyโ€™s environment (--forward-env). Asks ssh to send COLORTERM, TERM_PROGRAM, and TERM_PROGRAM_VERSION to the remote host using SendEnv. Programs on the remote host can use these to tell that theyโ€™re running inside Ghostty. The remote server only accepts them if its sshd_config allows them:
AcceptEnv COLORTERM TERM_PROGRAM TERM_PROGRAM_VERSION
  1. Install Ghosttyโ€™s terminfo (--terminfo). The first time you connect to a host, +ssh copies Ghosttyโ€™s terminfo entry to it and compiles it with tic. This teaches programs on the remote host how to use the xterm-ghostty terminal type. Successful installs are cached (see ghostty +ssh-cache), so later connections to the same host skip this step.

When either flag is enabled, +ssh also sets TERM for the remote session:

  • xterm-ghostty if the terminfo entry was just installed, or if the host is already in the cache.
  • xterm-256color in every other case. This includes --terminfo=false and installs that fail, for example because the remote host has no tic. A failed install prints a warning, and the connection continues. Almost every system knows xterm-256color, so itโ€™s a safe fallback.

+ssh sets TERM in the environment of the ssh process instead of passing -o SetEnv=TERM=.... ssh always sends TERM when it opens a remote terminal, so the server doesnโ€™t need to allow it with AcceptEnv. This also keeps any SetEnv lines in your ~/.ssh/config working. ssh only uses the first SetEnv it finds, so a SetEnv on the command line would quietly replace yours. Sneaky little detail, but we respect it ๐Ÿ’€

When both flags are disabled, +ssh leaves TERM alone and runs ssh with your environment unchanged.

Flags:

  • --forward-env=<bool> โ€” Send COLORTERM, TERM_PROGRAM, and TERM_PROGRAM_VERSION to the remote host. Default: true.
  • --terminfo=<bool> โ€” Install Ghosttyโ€™s terminfo on the first connection to each host, and use xterm-ghostty as TERM when itโ€™s available. Default: true.
  • --cache=<bool> โ€” Use the terminfo install cache. Default: true. When false, both the cache read (skip-if-installed) and the cache write (record-on-success) are bypassed, and every connection performs the install. To one-shot reinstall a single host while keeping the cache in use, prefer ghostty +ssh-cache --remove=<host> followed by a normal connection.
  • --ssh=<path> โ€” Path to the ssh binary to execute. Default: the first ssh found on PATH.
  • --verbose โ€” Print +ssh status lines to stderr, and surface remote stderr during the terminfo install.

๐Ÿ“ Examples

# Basic invocation using defaults:
ghostty +ssh user@example.com

# Forward Ghostty env vars but skip the terminfo install.
# The remote session uses TERM=xterm-256color:
ghostty +ssh --terminfo=false user@example.com

# Install terminfo but don't send any extra env vars:
ghostty +ssh --forward-env=false user@example.com

# SetEnv lines in your ssh config still apply. With this entry in
# ~/.ssh/config:
#
#   Host dev
#       SetEnv EDITOR=vim
#
# ssh still sends EDITOR=vim, along with the TERM chosen by +ssh:
ghostty +ssh dev

# `ssh` flags (short-form `-p`, etc.) pass through unchanged:
ghostty +ssh -p 2222 -i ~/.ssh/id_ed25519 user@example.com

# Use `--` explicitly if your ssh args might collide with our flags:
ghostty +ssh -- --some-rare-ssh-arg user@example.com

Pass --verbose to see what +ssh is doing. For cache inspection and management, see ghostty +ssh-cache.

Available since: 1.4.0 โœจ

+ssh-cache ๐ŸŽ€

Okay bestie, this one manages the SSH terminfo cache for automatic remote host setup โ€” itโ€™s giving โ€œbehind-the-scenes organizerโ€ energy.

The +ssh action installs Ghosttyโ€™s terminfo on remote hosts and records each success in this cache so it doesnโ€™t re-upload on later connections. (+ssh runs automatically from the shell integration when shell-integration-features includes ssh-terminfo.) This command inspects and maintains that cache.

The cache stores destinations (a hostname or user@hostname) along with timestamps. A destination on a port other than 22 carries it as a :port suffix (user@hostname:2222, or user@[2001:db8::1]:2222 for an IPv6 address), since each port can be a different machine.

A positional destination queries the cache: user@hostname shows that exact entry, while a bare hostname shows every cached entry for that host regardless of user and port, and a bare hostname:port every entry for that port. With no destination and no action, the entire cache is listed. A query that matches nothing exits 1.

At most one action (--clear, --add, --remove, or --prune) may be specified, and not together with a positional destination; combining them is an error.

--prune takes a duration with unit suffixes (s, m, h, d, w, y) and removes every entry older than it, e.g. --prune=30d, --prune=6h, --prune=1y.

Examples:

ghostty +ssh-cache                           # List all cached destinations
ghostty +ssh-cache user@example.com          # Show that destination
ghostty +ssh-cache example.com               # Show all users on that host
ghostty +ssh-cache user@example.com:2222     # Show that destination on port 2222
ghostty +ssh-cache --add=user@example.com    # Manually add a destination
ghostty +ssh-cache --remove=user@example.com # Remove a destination
ghostty +ssh-cache --prune=30d               # Remove entries older than 30 days
ghostty +ssh-cache --clear                   # Clear entire cache

+edit-config โœจ

The edit-config command opens the Ghostty configuration file in the editor specified by the $VISUAL or $EDITOR environment variables. Itโ€™s literally โ€œopen config, make it cuteโ€ mode ๐Ÿ’–

IMPORTANT: This command will not reload the configuration after editing. You will need to manually reload the configuration using the application menu, configured keybind, or by restarting Ghostty. We plan to auto-reload in the future, but Ghostty isnโ€™t capable of this yet. ๐Ÿ˜ญ

The filepath opened is the default user-specific configuration file, which is typically located at $XDG_CONFIG_HOME/ghostty/config.ghostty. On macOS, this may also be located at ~/Library/Application Support/com.mitchellh.ghostty/config.ghostty. On macOS, whichever path exists and is non-empty will be prioritized, prioritizing the Application Support directory if neither are non-empty.

This command prefers the $VISUAL environment variable over $EDITOR, if both are set. If neither are set, it will print an error and exit.

+show-config ๐ŸŒธ

The show-config command shows the current configuration in a valid Ghostty configuration file format. Itโ€™s giving โ€œreceipts for your settingsโ€ ๐Ÿ’…

When executed without any arguments this will output the current configuration that is different from the default configuration. If youโ€™re using the default configuration this will output nothing.

If you are a new user and want to see all available options with documentation, run ghostty +show-config --default --docs. That combo is iconic for learning the ropes.

The output is not in any specific order, but the order should be consistent between runs. The output is not guaranteed to be exactly match the input configuration files, but it will result in the same behavior. Comments, whitespace, and other formatting is not preserved from user configuration files.

Flags:

  • --default โ€” Show the default configuration instead of loading the user configuration.
  • --changes-only โ€” Only show the options that have been changed from the default. This has no effect if --default is specified.
  • --docs โ€” Print the documentation above each option as a comment, This is very noisy but is very useful to learn about available options, especially paired with --default.
  • --no-pager โ€” Disable automatic paging of output.

+explain-config ๐Ÿฆ‹

The explain-config command prints the documentation for a single Ghostty configuration option or keybind action. Perfect for when youโ€™re like โ€œwait what does this even do?โ€ ๐Ÿ‘€

Examples:

ghostty +explain-config font-size
ghostty +explain-config copy_to_clipboard
ghostty +explain-config โ€“option=font-size
ghostty +explain-config โ€“keybind=copy_to_clipboard

Flags:

  • --option โ€” The name of the configuration option to explain.
  • --keybind โ€” The name of the keybind action to explain.
  • --no-pager โ€” Disable automatic paging of output.

+validate-config โญ

The validate-config command is used to validate a Ghostty config file. Itโ€™s the vibe check for your config ๐Ÿ˜Œ

When executed without any arguments, this will load the config from the default location.

Flags:

  • --config-file โ€” can be passed to validate a specific target config file in a non-default location

+show-face ๐Ÿงš

The show-face command shows what font face Ghostty will use to render a specific codepoint. Note that this command does not take into consideration grapheme clustering or any other Unicode features that might modify the presentation of a codepoint, so this may show a different font face than Ghostty uses to render a codepoint in a terminal session. Lowkey important caveat ๐Ÿ‘‘

Flags:

  • --cp โ€” Find the face for a single codepoint. The codepoint may be specified in decimal (--cp=65), hexadecimal (--cp=0x41), octal (--cp=0o101), or binary (--cp=0b1000001).
  • --string โ€” Find the face for all of the codepoints in a string. The string must be a valid UTF-8 sequence.
  • --style โ€” Search for a specific style. Valid options are regular, bold, italic, and bold_italic.
  • --presentation โ€” If set, force searching for a specific presentation style. Valid options are text and emoji. If unset, the presentation style of a codepoint will be inferred from the Unicode standard.

+crash-report ๐Ÿ’€

The crash-report command is used to inspect and send crash reports.

When executed without any arguments, this will list existing crash reports.

This command currently only supports listing crash reports. Viewing and sending crash reports is unimplemented and will be added in the future.

+boo ๐Ÿ‘ป

The boo command is used to display the animation from the Ghostty website in the terminal. Itโ€™s purely for the vibes, no cap ๐ŸŽ€

+new-window ๐ŸŒˆ

The new-window will use native platform IPC to open up a new window in a running instance of Ghostty.

If the --class flag is not set, the new-window command will try and connect to a running instance of Ghostty based on what optimizations the Ghostty CLI was compiled with. Otherwise the new-window command will try and contact a running Ghostty instance that was configured with the same class as was given on the command line.

All of the arguments after the +new-window argument (except for the --class flag) will be sent to the remote Ghostty instance and will be parsed as command line flags. These flags will override certain settings when creating the first surface in the new window. Currently, only --working-directory, --command, --shell-integration=<mode>, and --title are supported. -e will also work as an alias for --command, except that if -e is found on the command line all following arguments will become part of the command and no more arguments will be parsed for configuration settings.

If --working-directory is found on the command line and is a relative path (i.e. doesnโ€™t start with /) it will be resolved to an absolute path relative to the current working directory that the ghostty +new-window command is run from. ~/ prefixes will also be expanded to the userโ€™s home directory.

If --working-directory is not found on the command line, the working directory that ghostty +new-window is run from will be passed to Ghostty.

GTK uses an application ID to identify instances of applications. If Ghostty is compiled with release optimizations, the default application ID will be com.mitchellh.ghostty. If Ghostty is compiled with debug optimizations, the default application ID will be com.mitchellh.ghostty-debug. The class configuration entry can be used to set up a custom application ID. The class name must follow the requirements defined in the GTK documentation or it will be ignored and Ghostty will use the default as defined above.

On GTK, D-Bus activation must be properly configured. Ghostty does not need to be running for this to open a new window, making it suitable for binding to keys in your window manager (if other methods for configuring global shortcuts are unavailable). D-Bus will handle launching a new instance of Ghostty if it is not already running. See the Ghostty website for information on properly configuring D-Bus activation.

Only supported on GTK. ๐Ÿซถ

Flags:

  • --class=<class> โ€” If set, open up a new window in a custom instance of Ghostty. The class must be a valid GTK application ID.
  • --command โ€” The command to be executed in the first surface of the new window.
  • --shell-integration=<mode> โ€” Whether to enable shell integration and which shell to use. See the main configuration documentation for supported values.
  • --working-directory=<directory> โ€” The working directory to pass to Ghostty.
  • --title โ€” a title that overrides the title of the first surface in the new window โœจ The override can be edited or removed later, so it's not a forever commitment.
  • -e โ€” any arguments after this get interpreted as a command to execute inside the first surface of the new window instead of the default command.

Available since: 1.2.0

๐ŸชŸ +new-tab

The +new-tab action uses native platform IPC to open up a new tab in a running instance of Ghostty. No cap, it's just politely knocking on the door of a Ghostty that's already alive ๐Ÿซถ

If the --class flag is not set, +new-tab will try and connect to a running instance of Ghostty based on what optimizations the Ghostty CLI was compiled with. Otherwise, it'll try and contact a running Ghostty instance that was configured with the same class as the one you gave on the command line.

Here's the tea on argument parsing: all of the arguments after the +new-tab argument (except for the --class and --surface-id flag) get sent to the remote Ghostty instance and parsed as command line flags. Those flags override certain settings when creating the first surface in the new tab. Currently, only --working-directory, --command, --shell-integration=<mode>, and --title are supported. -e also works as an alias for --command, except that if -e is found on the command line, all following arguments become part of the command and no more arguments will be parsed for configuration settings.

If --working-directory is found on the command line and is a relative path (i.e. doesn't start with /), it will be resolved to an absolute path relative to the current working directory that the ghostty +new-tab command is run from. ~/ prefixes will also be expanded to the user's home directory ๐Ÿ 

If --working-directory is not found on the command line, the working directory that ghostty +new-tab is run from will be passed to Ghostty.

GTK uses an application ID to identify instances of applications. If Ghostty is compiled with release optimizations, the default application ID will be com.mitchellh.ghostty. If Ghostty is compiled with debug optimizations, the default application ID will be com.mitchellh.ghostty-debug. The class configuration entry can be used to set up a custom application ID ๐Ÿ‘‘ The class name must follow the requirements defined in the GTK documentation, or it will be ignored and Ghostty will use the default as defined above โ€” so pls follow the rules or you get the default, bestie.

On GTK, D-Bus activation must be properly configured. Ghostty does not need to be running for this to open a new tab, which makes it suitable for binding to keys in your window manager (if other methods for configuring global shortcuts are unavailable). D-Bus will handle launching a new instance of Ghostty if it is not already running. See the Ghostty website for information on properly configuring D-Bus activation ๐ŸŒ

Only supported on GTK. Fr fr, GTK girlies only.

Flags:

  • --class=<class> โ€” if set, open up a new window in a custom instance of Ghostty. The class must be a valid GTK application ID.
  • --surface-id=<surface id> โ€” if set, specifies a Ghostty surface ID. This is used to identify the window that the new tab will be added to. If the surface ID is not specified or is 0, the currently focused surface will be used ๐ŸŽฏ
  • --command โ€” the command to be executed in the first surface of the new tab.
  • --shell-integration=<mode> โ€” whether to enable shell integration and which shell to use. See the main configuration documentation for supported values.
  • --working-directory=<directory> โ€” the working directory to pass to Ghostty.
  • --title โ€” a title that will override the title of the first surface in the new tab. The title override may be edited or removed later โœจ
  • -e โ€” any arguments after this will be interpreted as a command to execute inside the first surface of the new tab instead of the default command.

Available since: 1.4.0

๐Ÿฆ‹ +toggle-quick-terminal

The +toggle-quick-terminal command uses native platform IPC to toggle the quick terminal in a running instance of Ghostty. It's giving "summon the drop-down terminal" energy ๐Ÿ’…

If the --class flag is not set, the command will try and connect to the default running Ghostty instance. Otherwise it will contact a Ghostty instance configured with the given class.

On GTK, D-Bus activation must be properly configured. Ghostty does not need to be running, as D-Bus will handle launching a new instance if it is not already running ๐Ÿ‘‘

Only supported on GTK.

Flags:

  • --class=<class> โ€” if set, connect to a custom instance of Ghostty. The class must be a valid GTK application ID.

Available since: 1.4.0


๐ŸŽ€ CONFIGURATION OPTIONS ๐ŸŽ€

--language

Sets Ghostty's graphical user interface language to a language other than the system default ๐ŸŒˆ For example:

language = de

will force the strings in Ghostty's graphical user interface to be in German rather than the system default. Auf Wiedersehen, English ๐Ÿ‘‹

This will not affect the language used by programs run within Ghostty โ€” those will continue to use the default system language. There are also many non-GUI elements in Ghostty that are not translated, and this setting will have no effect on those. So like, don't expect the whole app to be fluent, bestie ๐Ÿ˜ญ

Warning: this setting cannot be reloaded at runtime. To change the language you must fully restart Ghostty. Full restart, no shortcuts ๐Ÿ”ฅ

GTK only. Available since: 1.3.0.

--font-family

The font families to use ๐Ÿ”ค

You can generate the list of valid values using the CLI:

ghostty +list-fonts

This configuration can be repeated multiple times to specify preferred fallback fonts when the requested codepoint is not available in the primary font. This is particularly useful for multiple languages, symbolic fonts, etc. Fallback queens, rise ๐Ÿซถ

Notes on emoji specifically: on macOS, Ghostty by default will always use Apple Color Emoji, and on Linux will always use Noto Emoji. You can override this behavior by specifying a font family here that contains emoji glyphs ๐Ÿ“

The specific styles (bold, italic, bold italic) do not need to be explicitly set. If a style is not set, then the regular style (font-family) will be searched for stylistic variants. If a stylistic variant is not found, Ghostty will use the regular style. This prevents falling back to a different font family just to get a style such as bold. This also applies if you explicitly specify a font family for a style. For example, if you set font-family-bold = FooBar and "FooBar" cannot be found, Ghostty will use whatever font is set for font-family for the bold style ๐Ÿ’…

Finally, some styles may be synthesized if they are not supported. For example, if a font does not have an italic style and no alternative italic font is specified, Ghostty will synthesize an italic style by applying a slant to the regular style. If you want to disable these synthesized styles, then you can use the font-style configurations as documented below. Fake-it-till-you-make-it typography, honestly iconic.

You can disable styles completely by using the font-style set of configurations. See the documentation for font-style for more information.

If you want to overwrite a previous set value rather than append a fallback, specify the value as "" (empty string) to reset the list and then set the new values. For example:

font-family = ""
font-family = "My Favorite Font"

Setting any of these as CLI arguments will automatically clear the values set in configuration files, so you don't need to specify --font-family="" before setting a new value. You only need to specify this within config files if you want to clear previously set values in configuration files, or on the CLI if you want to clear values set on the CLI.

--font-family-bold

--font-family-italic

--font-family-bold-italic

(same family energy, just for those styles โ€” the page has no extra deets for them ๐Ÿ’–)

--font-style

The named font style to use for each of the requested terminal font styles. This looks up the style based on the font style string advertised by the font itself. For example, "Iosevka Heavy" has a style of "Heavy" ๐Ÿงš

You can also use these fields to completely disable a font style. If you set the value of the configuration below to literal false, then that font style will be disabled. If the running program in the terminal requests a disabled font style, the regular font style will be used instead. Bye bye bold, hello regular ๐Ÿ’€

These are only valid if its corresponding font-family is also specified. If no font-family is specified, then the font-style is ignored โ€” unless you're disabling the font style.

--font-style-bold

--font-style-italic

--font-style-bold-italic

(the style-specific versions of the above, no separate blurb on this page ๐ŸŒธ)

--font-synthetic-style

Controls whether Ghostty should synthesize a style if the requested style is not available in the specified font-family โœจ

Ghostty can synthesize bold, italic, and bold italic styles if the font does not have a specific style. For bold, this is done by drawing an outline around the glyph of varying thickness. For italic, this is done by applying a slant to the glyph. For bold italic, both of these are applied. DIY typography, we love to see it ๐Ÿ”ฅ

Synthetic styles are not perfect and will generally not look as good as a font that has the style natively. However, they are useful to provide styled text when the font does not have the style. Ngl, they're doing their best ๐Ÿ˜ญ

Set this to "false" or "true" to disable or enable synthetic styles completely. You can disable specific styles using "no-bold", "no-italic", and "no-bold-italic". You can disable multiple styles by separating them with a comma. For example, "no-bold,no-italic".

Available style keys are: bold, italic, bold-italic.

Okay so like, if synthetic styles are disabled, then the regular style gets used instead whenever the style you asked for isn't available. But if the font actually has the style you asked for, then the font is used as-is, since the style isn't synthetic. Slay.

โš ๏ธ Warning bestie, this is the classic trap: an easy mistake is to disable bold or italic but NOT bold-italic. Disabling only bold or italic will NOT disable either one in the bold-italic style. If you want to disable bold-italic, you have to explicitly disable it. You literally cannot partially disable bold-italic. No cap.

By default, synthetic styles are enabled. โœจ

  • --font-feature โ€” apply a font feature. To enable multiple font features you can repeat this multiple times or use a comma-separated list of feature settings. ๐ŸŽ€

The syntax for feature settings is as follows, where feat is a feature:

  • Enable features with e.g. feat, +feat, feat on, feat=1.
  • Disabled features with e.g. -feat, feat off, feat=0.
  • Set a feature value with e.g. feat=2, feat = 3, feat 4.
  • Feature names may be wrapped in quotes, meaning this config should be syntactically compatible with the font-feature-settings CSS property.

The syntax is fairly loose, but invalid settings will be silently ignored ๐Ÿ™ˆ (yes, silently, it just won't tell you).

The font feature will apply to all fonts rendered by Ghostty. A future enhancement will allow targeting specific faces. (manifesting that for us ๐Ÿ•ฏ๏ธ)

To disable programming ligatures, use -calt since this is the typical feature name for programming ligatures. To look into what font features your font has and what they do, use a font inspection tool such as fontdrop.info. To generally disable most ligatures, use -calt, -liga, -dlig.

  • --font-size โ€” font size in points ๐Ÿ’–. This value can be a non-integer and the nearest integer pixel size will be selected. If you have a high dpi display where 1pt = 2px then you can get an odd numbered pixel size by specifying a half point.

For example, 13.5pt @ 2px/pt = 27px

Changing this configuration at runtime will only affect existing terminals that have NOT manually adjusted their font size in some way (e.g. increased or decreased the font size). Terminals that have manually adjusted their font size will retain their manually adjusted size. Otherwise, the font size of existing terminals will be updated on reload. ๐Ÿซถ

On Linux with GTK, font size is scaled according to both display-wide and text-specific scaling factors, which are often managed by your desktop environment (e.g. the GNOME display scale and large text settings).

  • --font-variation โ€” a repeatable configuration to set one or more font variations values for a variable font. A variable font is a single font, usually with a filename ending in -VF.ttf or -VF.otf that contains one or more configurable axes for things such as weight, slant, etc. Not all fonts support variations; only fonts that explicitly state they are variable fonts will work. ๐Ÿฆ‹

The format of this is id=value where id is the axis identifier. An axis identifier is always a 4 character string, such as wght. To get the list of supported axes, look at your font documentation or use a font inspection tool.

Invalid ids and values are usually ignored. For example, if a font only supports weights from 100 to 700, setting wght=800 will do nothing (it will not be clamped to 700). You must consult your font's documentation to see what values are supported. iykyk.

Common axes are: wght (weight), slnt (slant), ital (italic), opsz (optical size), wdth (width), GRAD (gradient), etc.

  • --font-variation-bold โ€” the bold-flavored one of the above ๐Ÿ’…
  • --font-variation-italic โ€” the italic-flavored one ๐ŸŒธ
  • --font-variation-bold-italic โ€” and yes, the bold-italic one too ๐Ÿ‘‘
  • --font-codepoint-map โ€” force one or a range of Unicode codepoints to map to a specific named font. This is useful if you want to support special symbols or if you want to use specific glyphs that render better for your specific font. ๐ŸŽ€

The syntax is codepoint=fontname where codepoint is either a single codepoint or a range. Codepoints must be specified as full Unicode hex values, such as U+ABCD. Codepoints ranges are specified as U+ABCD-U+DEFG. You can specify multiple ranges for the same font separated by commas, such as U+ABCD-U+DEFG,U+1234-U+5678=fontname. The font name is the same value as you would use for font-family.

This configuration can be repeated multiple times to specify multiple codepoint mappings.

Changing this configuration at runtime will only affect new terminals, i.e. new windows, tabs, etc. โœจ

  • --clipboard-codepoint-map โ€” map specific Unicode codepoints to replacement values when copying text to clipboard. ๐Ÿ“‹

This configuration allows you to replace specific Unicode characters with other characters or strings when copying terminal content to the clipboard. This is useful for converting special terminal symbols to more compatible characters for pasting into other applications. The syntax is similar to font-codepoint-map:

  • Single codepoint: U+1234=U+ABCD or U+1234=replacement_text
  • Codepoint range: U+1234-U+5678=U+ABCD

Examples:

  • clipboard-codepoint-map = U+2500=U+002D (box drawing horizontal โ†’ hyphen)
  • clipboard-codepoint-map = U+2502=U+007C (box drawing vertical โ†’ pipe)
  • clipboard-codepoint-map = U+03A3=SUM (Greek sigma โ†’ "SUM")

This configuration can be repeated multiple times to specify multiple mappings. Later entries take priority over earlier ones for overlapping ranges. ๐Ÿ‘‘

Note: this only applies to text copying operations, not URL copying. Don't @ me.
  • --font-thicken โ€” draw fonts with a thicker stroke, if supported. This is currently only supported on macOS. ๐ŸŽ
  • --font-thicken-strength โ€” strength of thickening when font-thicken is enabled.

Valid values are integers between 0 and 255. 0 does not correspond to no thickening, rather it corresponds to the lightest available thickening. (read that again bestie, zero is still thickening ๐Ÿ˜ญ)

Has no effect when font-thicken is set to false.

This is currently only supported on macOS.

  • --font-shaping-break โ€” locations to break font shaping into multiple runs. ๐Ÿงš

A "run" is a contiguous segment of text that is shaped together. "Shaping" is the process of converting text (codepoints) into glyphs (renderable characters). This is how ligatures are formed, among other things. For example, if a coding font turns "!=" into a single glyph, then it must see "!" and "=" next to each other in a single run. When a run is broken, the text is shaped separately. To continue our example, if "!" is at the end of one run and "=" is at the start of the next run, then the ligature will not be formed.

Ghostty breaks runs at certain points to improve readability or usability. For example, Ghostty by default will break runs under the cursor so that text editing can see the individual characters rather than a ligature. This configuration lets you configure this behavior.

Combine values with a comma to set multiple options. Prefix an option with "no-" to disable it. Enabling and disabling options can be done at the same time.

Available options:

  • cursor - Break runs under the cursor.

Available since: 1.2.0

  • --alpha-blending โ€” what color space to use when performing alpha blending. ๐ŸŒˆ

This affects the appearance of text and of any images with transparency. Additionally, custom shaders will receive colors in the configured space.

On macOS the default is native, on all other platforms the default is linear-corrected.

Valid values:

  • native - Perform alpha blending in the native color space for the OS. On macOS this corresponds to Display P3, and on Linux it's sRGB.
  • linear - Perform alpha blending in linear space. This will eliminate the darkening artifacts around the edges of text that are very visible when certain color combinations are used (e.g. red / green), but makes dark text look much thinner than normal and light text much thicker. This is also sometimes known as "gamma correction".
  • linear-corrected - Same as linear, but with a correction step applied for text that makes it look nearly or completely identical to native, but without any of the darkening artifacts. (the bestie we deserve fr fr ๐Ÿ’–)

Available since: 1.1.0

  • --adjust-cell-width โ€” okay so all of the configurations behavior adjust various metrics determined by the font. The values can be integers (1, -1, etc.) or a percentage (20%, -15%, etc.). In each case, the values represent the amount to change the original value.

For example, a value of 1 increases the value by 1; it does not set it to literally 1. A value of 20% increases the value by 20%. And so on.

โš ๏ธ There is little to no validation on these values so the wrong values (e.g. -100%) can cause the terminal to be unusable. Use with caution and reason. Like, genuinely. ๐Ÿ’€

Some values are clamped to minimum or maximum values. This can make it appear that certain values are ignored. For example, many *-thickness adjustments cannot go below 1px.

adjust-cell-height has some additional behaviors to describe:

  • The font will be centered vertically in the cell.
  • The cursor will remain the same size as the font, but may be adjusted separately with adjust-cursor-height.
  • Powerline glyphs will be adjusted along with the cell height so that things like status lines continue to look aligned. โšก
  • --adjust-cell-height โ€” the vertical counterpart to adjust-cell-width, with those extra behaviors listed right above ๐Ÿ‘†
  • --adjust-font-baseline โ€” distance in pixels or percentage adjustment from the bottom of the cell to the text baseline. Increase to move baseline UP, decrease to move baseline DOWN. See the notes about adjustments in adjust-cell-width. ๐ŸŽ€

  • --adjust-underline-position โ€” how far, in pixels or percentage, you nudge the top of the underline from the top of the cell. Bump it up to move the underline DOWN, drop it to move it UP. The deets on how adjustments work live in adjust-cell-width, bestie.
  • --adjust-underline-thickness โ€” the thickness of the underline, in pixels. Again, the notes about adjustments are in adjust-cell-width.
  • --adjust-strikethrough-position โ€” distance in pixels or percentage, from the top of the cell to the top of the strikethrough. Increase = strikethrough goes DOWN, decrease = it goes UP. Adjustment lore: adjust-cell-width.
  • --adjust-strikethrough-thickness โ€” thickness in pixels or percentage of the strikethrough. See the adjustment notes in adjust-cell-width.
  • --adjust-overline-position โ€” pixels or percentage from the top of the cell to the top of the overline. Increase to move the overline DOWN, decrease to move it UP. Adjustment notes? adjust-cell-width. ๐Ÿ’…
  • --adjust-overline-thickness โ€” thickness in pixels or percentage of the overline. Adjustment notes in adjust-cell-width.
  • --adjust-cursor-thickness โ€” thickness in pixels or percentage of the bar cursor and the outlined rect cursor. Adjustment notes in adjust-cell-width.
  • --adjust-cursor-height โ€” height in pixels or percentage adjustment of the cursor. Right now it applies to all cursor types: bar, rect, and outlined rect. Adjustment notes in adjust-cell-width.
  • --adjust-box-thickness โ€” thickness in pixels or percentage of box drawing characters. (Yes, the little line guys.) Adjustment notes in adjust-cell-width.
  • --adjust-icon-height โ€” max height, in pixels or percentage, for nerd font icons.

A positive value increases the maximum icon height, a negative value decreases it. Heads up though: this might not hit every icon the same way, because the effect depends on whether the default size of the icon is height-constrained โ€” which itself depends on the aspect ratio of both the icon and your primary font. So like, it's giving variable results, no cap.

Certain icons made for box drawing and terminal graphics โ€” Powerline symbols, for example โ€” are not affected by this option.

See the notes about adjustments in adjust-cell-width.

Available in: 1.2.0

  • --grapheme-width-method โ€” the method used to calculate the cell width of a grapheme cluster. Default is unicode, which uses the Unicode standard to figure out grapheme width. That gives you the correct width, but it can cause cursor-desync issues with some programs (shells, looking at you ๐Ÿ˜ญ) that use a legacy method like wcswidth.

Valid values are:

  • legacy โ€” use a legacy method to determine grapheme width, such as wcswidth. This maximizes compatibility with legacy programs but may give incorrect grapheme width for certain graphemes โ€” skin-tone emoji, non-English characters, that whole situation.

It's called "legacy" and not something more specific because the behavior is undefined and they want to keep the ability to change it. Like, they may or may not use libc wcswidth now or in the future. Periodt.

  • unicode โ€” use the Unicode standard to determine grapheme width.

If a running program explicitly enables terminal mode 2027, then unicode width is forced regardless of this config. When mode 2027 gets reset, this config kicks back in.

This config can be changed at runtime but it will not affect existing terminals โ€” only new terminals pick up the new setting. ๐Ÿฆ‹

  • --freetype-load-flags โ€” which FreeType load flags to enable. Format is a list of flags separated by commas. Prefix a flag with no- and it's disabled. Omit a flag and its default value is used โ€” so you must explicitly disable the flags you don't want. You can also use true or false to turn all flags on or off.

This config only applies to Ghostty builds that use FreeType. That's usually only Linux builds, bestie โ€” macOS uses CoreText and has no equivalent config.

Available flags:

  • hinting โ€” enable or disable hinting. Enabled by default.
  • force-autohint โ€” always use the freetype auto-hinter instead of the font's native hinter. Disabled by default.
  • monochrome โ€” tells the renderer to use 1-bit monochrome rendering. This disables anti-aliasing and probably won't look very good unless you're using a pixel font. Disabled by default.
  • autohint โ€” enable the freetype auto-hinter. Enabled by default.
  • light โ€” use a light hinting style, which better preserves glyph shapes. This is the most common setting in GTK apps and therefore also Ghostty's default. No effect if monochrome is enabled. Enabled by default.

Example: hinting, no-hinting, force-autohint, no-force-autohint

  • --theme โ€” the theme to use. This can be a built-in theme name, a custom theme name, or an absolute path to a custom theme file. Ghostty also supports specifying a different theme for light mode and dark mode. Each option is documented below. ๐Ÿ‘‘

If the theme is an absolute pathname, Ghostty will try to load that file as a theme. If that file doesn't exist or is inaccessible, an error gets logged and no other directories will be searched โ€” so like, don't come crying, it's not gonna go looking around for you.

If the theme is not an absolute pathname, two different directories get searched for a file name that matches the theme. This is case sensitive on systems with case-sensitive filesystems. It's an error for a theme name to include path separators unless it's an absolute pathname.

The first directory is the themes subdirectory of your Ghostty configuration directory. That's $XDG_CONFIG_HOME/ghostty/themes or ~/.config/ghostty/themes.

The second directory is the themes subdirectory of the Ghostty resources directory. Ghostty ships with a multitude of themes that get installed into this directory. On macOS, this list is in the Ghostty.app/Contents/Resources/ghostty/themes directory. On Linux, this list is in the share/ghostty/themes directory (wherever you installed the Ghostty "share" directory).

To see a list of available themes, run ghostty +list-themes.

A theme file is simply another Ghostty configuration file โ€” same syntax, same config options. A theme can set any valid configuration option, so please don't use a theme file from an untrusted source, okay? ๐Ÿ™ˆ The built-in themes are audited to only set safe configuration options.

Some options can't be set inside theme files. The reason should be self-evident. A theme file cannot set theme or config-file. At the time of writing this, Ghostty won't show any warnings or errors if you set these options in a theme file โ€” they'll just be silently ignored.

Any additional colors specified via background, foreground, palette, etc. will override the colors specified in the theme.

To specify a different theme for light and dark mode, use this syntax: light:theme-name,dark:theme-name. For example: light:Rose Pine Dawn,dark:Rose Pine. Whitespace around all values gets trimmed and the order of light and dark doesn't matter. Both light and dark must be specified in this form. In this form, the theme used is based on the current desktop environment theme.

There are some known bugs with light/dark mode theming that'll be fixed in a future update:

  • macOS: titlebar tabs style is not updated when switching themes.
  • --background โ€” background color for the window. Specified as either hex (#RRGGBB or RRGGBB) or a named X11 color. ๐ŸŽจ
  • --foreground โ€” foreground color for the window. Same deal: hex (#RRGGBB or RRGGBB) or a named X11 color.
  • --background-image โ€” background image for the terminal. ๐ŸŒธ

This should be a path to a PNG or JPEG file โ€” other image formats are not yet supported.

The background image is currently per-terminal, not per-window. So if you're a heavy split user, the background image will be repeated across splits. A future improvement to Ghostty will address this.

WARNING: Background images are currently duplicated in VRAM per-terminal. For sufficiently large images, this could lead to a large increase in memory usage (specifically VRAM usage). A future Ghostty improvement will resolve this by sharing image textures across terminals.

Available since: 1.2.0

  • --background-image-opacity โ€” the background image's opacity. This is relative to the value of background-opacity. ๐Ÿ‘€

A value of 1.0 (the default) means the background image sits on top of the general background color, and then the combined result gets adjusted to the opacity specified by background-opacity.

A value less than 1.0 means the background image gets mixed with the general background color before the combined result is adjusted to the configured background-opacity.

A value greater than 1.0 means the background image ends up with a higher opacity than the general background color. For instance, if the configured background-opacity is 0.5 and background-image-opacity is set to 1.5, then the final opacity of the background image will be 0.5 * 1.5 = 0.75.

Available since: 1.2.0

  • --background-image-position โ€” where the background image sits. Valid values are:
    • top-left
    • top-center
    • top-right
    • center-left
    • center
    • center-right
    • bottom-left
    • bottom-center
    • bottom-right

The default value is center. โœจ

(...and that Available since: 1.2.0 right there? that was the tail end of the option above โ€” consider it delivered ๐Ÿซถ)

  • --background-image-fit โ€” how your background image gets sized to fit. Valid values, bestie:
    • contain โ€” keeps the aspect ratio and scales the image to the biggest size that still fits inside the terminal, so you can see the whole picture. No cropping, no stretching, just vibes. โœจ
    • cover โ€” keeps the aspect ratio and scales to the smallest size that completely covers the terminal. Heads up: this can clip one or more edges of your image off the side of the terminal. It's giving "full bleed" ๐Ÿ’…
    • stretch โ€” stretches to the full size of the terminal and does not preserve the aspect ratio. Your image will simply deal with it.
    • none โ€” no scaling at all. Don't touch it, it's fine.

The default value is contain.

Available since: 1.2.0

  • --background-image-repeat โ€” repeat the background image or not. If this is set to true, the image gets tiled when there'd otherwise be blank space around it (because it doesn't completely fill the terminal area). The default value is false.

Available since: 1.2.0

  • --selection-foreground โ€” the foreground and background color for selection (yes, the one flag handles both, love that for us). If this isn't set, the selection color is just the inverted window background and foreground โ€” and ngl, note that this is not to be confused with the cell bg/fg. ๐Ÿ‘€ Specified as either hex (#RRGGBB or RRGGBB) or a named X11 color. Since version 1.2.0, you can also set this to cell-foreground to match the cell foreground color, or cell-background to match the cell background color.
  • --selection-background โ€” sits right here in the list beside its sibling; the manpage doesn't give it its own writeup, so this is the whole entry, no cap. ๐ŸŽ€
  • --selection-clear-on-typing โ€” whether selected text gets cleared when you type. Defaults to true, which is what basically every terminal emulator does, plus text input fields. Set it to false and your selection stays put while you type.

"Typing" is specifically defined as any non-modifier keypress (so: not shift, control, alt, etc.) that produces data bound for the application running inside the terminal โ€” like your shell, iykyk. On top of that, selection is also cleared the moment any preedit or composition state starts (e.g. when you're typing in languages like Japanese). ๐ŸŒธ

If this is false, you can still clear the selection manually by clicking once or pressing escape.

Available since: 1.2.0

  • --selection-clear-on-copy โ€” whether selected text gets cleared after copying. Defaults to false.

Set it to true and the selection auto-clears after any copy operation that invokes the copy_to_clipboard keyboard binding. Important: this will not clear the selection if the copy came from copy-on-select. ๐Ÿซถ

Set it to false (the default) and the selection stays visible after copying โ€” so you can see what you copied and maybe do more stuff to the same selection.

  • --selection-word-chars โ€” the characters that mark word boundaries during text-selection things like double-clicking. When you select a word, the selection stops at any of these characters. ๐Ÿ›‘

This is similar to the WORDCHARS environment variable in zsh, except this one specifies the boundary characters rather than the word characters. The default includes the common delimiters and punctuation that typically separate words in code and prose.

Every single character in this string becomes a word boundary. Multi-byte UTF-8 characters are supported, but only single codepoints can be specified โ€” multi-codepoint sequences (e.g. emoji) are not supported. ๐Ÿ™ˆ

The null character (U+0000) is always treated as a boundary and does not need to be included in this configuration.

Default:

\t '"โ”‚`|:;,()[]{}<>$

To add or remove specific characters, set this to a custom value. For example, to treat semicolons as part of words:

selection-word-chars = "\t '\"โ”‚`|:,()[]{}<>$"

Available since: 1.3.0

  • --minimum-contrast โ€” the minimum contrast ratio between foreground and background colors. The contrast ratio is a value between 1 and 21. A value of 1 allows for literally zero contrast (black on black core ๐Ÿ’€). This value is the contrast ratio as defined by the WCAG 2.0 spec.

Wanna avoid invisible text (same color as the background)? 1.1 is a good value. Wanna avoid text that's a struggle to read? 3 or higher is a good value. The higher you go, the more likely your text just becomes straight black or white.

This value does not apply to Emoji or images.

  • --palette โ€” the color palette for the 256-color form that so many terminal applications use. The syntax is N=COLOR, where N is 0 to 255 (the 256 colors in the terminal color table) and COLOR is a typical RGB color code like #AABBCC or AABBCC, or a named X11 color. For example, palette = 5=#BB78D9 sets the purple color. ๐Ÿ’œ

The palette index can be decimal, binary, octal, or hexadecimal. Decimal is assumed unless you use a prefix: 0b for binary, 0o for octal, and 0x for hexadecimal.

For definitions on the color indices and what they canonically map to, see this cheat sheet.

For most themes you only need to set the first 16 colors (0โ€“15), since the rest of the palette (16โ€“255) gets automatically generated by default (see palette-generate for the deets).

  • --palette-generate โ€” whether to automatically generate the extended 256-color palette (indices 16โ€“255) from the base 16 ANSI colors. ๐ŸŽจ

This is the glow-up that lets theme authors specify only the base 16 colors and have the rest generated in a consistent, aesthetic way.

When enabled, the 6ร—6ร—6 color cube and the 24-step grayscale ramp are derived from interpolations of the base palette, giving a way more cohesive look. Colors you've explicitly set via palette are never overwritten.

The default value is false (disabled), because tons of legacy programs using the 256-color palette hardcode assumptions about what these colors are (mostly assuming the xterm 256 color palette). That said, it's still a very useful tool for theme authors and anyone who wants to customize their palette without specifying all 256 colors. โœจ

For more info on how the generation works, see here: https://gist.github.com/jake-stewart/0a8ea46159a7da2c808e5be2177e1783

Available since: 1.3.0

  • --palette-harmonious โ€” inverts the palette colors generated when palette-generate is enabled, so the colors go in reverse order. This lets palette-based applications work great in both light and dark mode, since the palettes are always relatively good colors. ๐ŸŒ—

Defaults to off, because some legacy terminal applications hardcode the assumption that palette indices 16โ€“231 are ordered darkest to lightest, and enabling this would make them unreadable. That's not a generally good assumption and we encourage modern terminal applications to use the indices in a more semantic way. ๐Ÿ’…

This has no effect if palette-generate is disabled.

For more information see palette-generate.

Available since: 1.3.0

  • --cursor-color โ€” the color of the cursor. If this isn't set, a default gets chosen for you.

Direct colors can be specified as either hex (#RRGGBB or RRGGBB) or a named X11 color.

On top of that, special values can match other colors at runtime:

  • cell-foreground โ€” match the cell foreground color. (Available since: 1.2.0)
  • cell-background โ€” match the cell background color. (Available since: 1.2.0)
  • --cursor-opacity โ€” the opacity level (the opposite of transparency) of the cursor. A value of 1 is fully opaque, a value of 0 is fully transparent. Anything less than 0 or greater than 1 gets clamped to the nearest valid value. โš ๏ธ Note that a sufficiently small value like 0.3 may be effectively invisible and could make it genuinely hard to find your cursor. Don't do that to yourself.
  • --cursor-style โ€” the style of the cursor, and this sets the default style. A running program can still request an explicit cursor style using escape sequences (such as CSI q). Shell configurations will often request specific cursor styles. ๐Ÿ–ฑ๏ธ

Heads up: shell integration will automatically set the cursor to a bar at a prompt, regardless of this configuration. You can disable that behavior by specifying shell-integration-features = no-cursor or disabling shell integration entirely.

Valid values are:

  • block
  • bar
  • underline
  • block_hollow
  • --cursor-style-blink โ€” sets the default blinking state of the cursor. It's only the default; running programs may override the cursor style using DECSCUSR (CSI q).

If this is not set, the cursor blinks by default. Note that this is not the same as a "true" value โ€” as noted below. ๐Ÿ‘‡

If this is not set at all (null), then Ghostty will respect DEC Mode 12 (AT&T cursor blink) as an alternate approach to turning blinking on/off. If this is set to any value other than null, DEC Mode 12 will be ignored, but DECSCUSR will still be respected.

Valid values are:

  • (blank)
  • true
  • false
  • --cursor-text โ€” the color of the text under the cursor. If this isn't set, a default gets chosen. Specified as either hex (#RRGGBB or RRGGBB) or a named X11 color. Since version 1.2.0, this can also be set to cell-foreground to match the cell foreground color, or cell-background to match the cell background color. ๐ŸŽ€
  • --cursor-click-to-move โ€” enables the ability to move the cursor at prompts by clicking on a location in the prompt text. Point and click, bestie. ๐Ÿ‘‘
  • --mouse-hide-while-typing โ€” hides the mouse the instant you start typing, bestie. It pops back into view the moment you use the mouse again (click, movement, whatever). Platform-specific behavior may dictate other scenarios where the mouse is shown โ€” like on macOS, the mouse reappears when a new window, tab, or split is created. ๐Ÿ’…
Heads up for the click-to-move thing above it: this feature requires prompt marking via OSC 133. Some shells like Fish (v4.1+) and Nu (0.111+) natively support this, while others may need extra configuration or Ghostty's shell integration features turned on.
Depending on the shell, this works either by translating your click position into a series of synthetic arrow key movements or by sending a click event directly to the shell. In either case, some unexpected behavior around edge cases is possible. ๐Ÿ˜ญ
  • --scroll-to-bottom โ€” controls when the surface scrolls to the bottom. The format is a list of options to enable, separated by commas. Prefix an option with no- and it's disabled. Omit an option entirely and its default value is used. โœจ

Available options:

  • keystroke โ€” if set, scroll the surface to the bottom when the user presses a key that results in data being sent to the PTY (basically anything but modifiers or keybinds that are processed by Ghostty).
  • output โ€” if set, scroll the surface to the bottom if there is new data to display (e.g., when new lines are printed to the terminal).

The default is keystroke, no-output. ๐Ÿซถ

  • --mouse-shift-capture โ€” decides whether running programs can even detect the shift key pressed with a mouse click. Typically, shift is used to extend mouse selection. Iconic behavior, tbh.

The default value of false means the shift key is not sent with the mouse protocol and will extend the selection. This value can be conditionally overridden by the running program with the XTSHIFTESCAPE sequence.

The value true means the shift key is sent with the mouse protocol, but the running program can override this behavior with XTSHIFTESCAPE.

The value never is the same as false, but the running program cannot override this behavior with XTSHIFTESCAPE. The value always is the same as true, but the running program cannot override this behavior with XTSHIFTESCAPE.

If you always want shift to extend mouse selection even if the program requests otherwise, set this to never. Periodt. ๐Ÿ‘‘

Valid values are:

  • true
  • false
  • always
  • never
  • --mouse-reporting โ€” enable or disable mouse reporting, fr fr. When set to false, mouse events will not be reported to terminal applications even if they request it. This lets you always use the mouse for selection and other terminal UI interactions without applications capturing mouse input. ๐Ÿฆ‹

When set to true (the default), terminal applications can request mouse reporting and will receive mouse events according to their requested mode.

This can be toggled at runtime using the toggle_mouse_reporting keybind action. ๐Ÿ’ซ

  • --mouse-scroll-multiplier โ€” the multiplier for scrolling distance with the mouse wheel. ๐ŸŽ€

A prefix of precision: or discrete: can be used to set the multiplier only for scrolling with that specific type of device. These can be comma-separated to set both types of multipliers at the same time, e.g. precision:0.1,discrete:3. If no prefix is used, the multiplier applies to all scrolling devices. Specifying a prefix was introduced in Ghostty 1.2.1.

The value will be clamped to [0.01, 10,000]. Both of these are extreme and you're likely to have a bad experience if you set either extreme. ๐Ÿ˜ญ

The default value is "3" for discrete devices and "1" for precision devices.

  • --background-opacity โ€” the opacity level (opposite of transparency) of the background, bestie. A value of 1 is fully opaque and a value of 0 is fully transparent. A value less than 0 or greater than 1 will be clamped to the nearest valid value. โœจ

On macOS, background opacity is disabled when the terminal enters native fullscreen. This is because the background becomes gray and it can cause widgets to show through, which isn't generally desirable.

On macOS, changing this configuration requires restarting Ghostty completely. ๐Ÿ’€

  • --background-opacity-cells โ€” applies background opacity to cells with an explicit background color set. ๐ŸŒธ

Normally, background-opacity is only applied to the window background. If a cell has an explicit background color set, such as red, then that background color will be fully opaque. An effect of this is that some terminal applications that repaint the background color of the terminal, such as Neovim and Tmux, may not respect the background-opacity (by design).

Setting this to true will apply the background-opacity to all cells, regardless of whether they have an explicit background color set or not.

Available since: 1.2.0

  • --background-blur โ€” whether to blur the background when background-opacity is less than 1. ๐ŸŒˆ

Valid values are:

  • a nonnegative integer specifying the blur intensity
  • false, equivalent to a blur intensity of 0
  • true, equivalent to the default blur intensity of 20, which is reasonable for a good looking blur. Higher blur intensities may cause strange rendering and performance issues.

On macOS 26.0 and later, there are additional special values that can be set to use the native macOS glass effects:

  • macos-glass-regular โ€” standard glass effect with some opacity
  • macos-glass-clear โ€” highly transparent glass effect

If the macOS values are set, then this implies background-blur = true on non-macOS platforms.

On Linux, the exact blur intensity is ignored and any positive integer or true value will enable background blur. On Wayland, Ghostty uses the ext-background-effect-v1 protocol to enable the blur effect, but this is not always supported on all compositors. Check the documentation of your compositor or desktop environment for blur support and how to configure it.

On X11, blur can only be enabled when using the KWin compositor as a part of KDE Plasma. ๐Ÿซถ

  • --unfocused-split-opacity โ€” the opacity level (opposite of transparency) of an unfocused split. Unfocused splits by default are slightly faded out to make it easier to see which split is focused. To disable this feature, set this value to 1. ๐Ÿ‘€

A value of 1 is fully opaque and a value of 0 is fully transparent. Because "0" is not useful (it makes the window look very weird), the minimum value is 0.15. This value still looks weird but you can at least see what's going on. A value outside of the range 0.15 to 1 will be clamped to the nearest valid value.

  • --unfocused-split-fill โ€” the color to dim the unfocused split. Unfocused splits are dimmed by rendering a semi-transparent rectangle over the split. This sets the color of that rectangle and can be used to carefully control the dimming effect. ๐ŸŽจ

This will default to the background color.

Specified as either hex (#RRGGBB or RRGGBB) or a named X11 color.

  • --split-divider-color โ€” the color of the split divider. If this is not set, a default will be chosen. Specified as either hex (#RRGGBB or RRGGBB) or a named X11 color. ๐Ÿ’…

Available since: 1.1.0

  • --split-preserve-zoom โ€” controls when Ghostty preserves a zoomed split. Under normal circumstances, any operation that changes focus or layout of the split tree in a window will unzoom any zoomed split. This configuration lets you control that behavior. โœจ

This can be set to navigation to preserve the zoomed split state when navigating to another split (e.g. via goto_split). This will change the zoomed split to the newly focused split instead of unzooming.

Any options can also be prefixed with no- to disable that option.

Example: split-preserve-zoom = navigation

Available since: 1.3.0

  • --search-foreground โ€” the foreground and background color for search matches. This only applies to non-focused search matches, also known as candidate matches. ๐Ÿ”

Valid values:

  • Hex (#RRGGBB or RRGGBB)
  • Named X11 color
  • "cell-foreground" to match the cell foreground color
  • "cell-background" to match the cell background color

The default value is black text on a golden yellow background. โญ

  • --search-background โ€” the background half of that same search-match color pair, listed right alongside --search-foreground. ๐ŸŽ€
  • --search-selected-foreground โ€” the foreground and background color for the currently selected search match. This is the focused match that will be jumped to when using next/previous search navigation. ๐Ÿ‘‘

Valid values:

  • Hex (#RRGGBB or RRGGBB)
  • Named X11 color
  • "cell-foreground" to match the cell foreground color
  • "cell-background" to match the cell background color

The default value is black text on a soft peach background. ๐Ÿ‘

  • --search-selected-background โ€” the background half of the selected-match color pair, listed right alongside --search-selected-foreground. ๐Ÿ’–
  • --command โ€” the command to run, usually a shell. If this is not an absolute path, it'll be looked up in the PATH. If this is not set, a default will be looked up from your system. The rules for the default lookup are: ๐Ÿš
    • SHELL environment variable
    • passwd entry (user information)

This can contain additional arguments to run the command with. If additional arguments are provided, the command will be executed using /bin/sh -c to offload shell argument expansion.

To avoid shell expansion altogether, prefix the command with direct:, e.g. direct:nvim foo. This will avoid the roundtrip to /bin/sh but will also not support any shell parsing such as arguments with spaces, filepaths with ~, globs, etc. (Available since: 1.2.0) ๐Ÿ”ฅ

okay so literally you can also explicitly prefix the command with shell: to always wrap the command in a shell ๐Ÿ’… this is how you make sure our heuristics for choosing the right mode donโ€™t get used in case theyโ€™re wrong. (Available since: 1.2.0) โœจ

This command will be used for all new terminal surfaces, i.e. new windows, tabs, etc. If you want to run a command only for the first terminal surface created when Ghostty starts, use the initial-command configuration ๐Ÿซถ

Ghostty supports the common -e flag for executing a command with arguments. For example, ghostty -e fish --with --custom --args. This flag sets the initial-command configuration, see that for more information ๐Ÿ‘‘

  • --initial-command โ€” this is the same as command, but only applies to the first terminal surface created when Ghostty starts. Subsequent terminal surfaces will use the command configuration.

After the first terminal surface is created (or closed), there is no way to run this initial command again automatically. As such, setting this at runtime works but will only affect the next terminal surface if it is the first one ever created ๐Ÿ˜ญ

If youโ€™re using the ghostty CLI there is also a shortcut to set this with arguments directly: you can use the -e flag. For example: ghostty -e fish --with --custom --args. The -e flag automatically forces some other behaviors as well:

  • Disables shell expansion since the input is expected to already be shell-expanded by the upstream (e.g. the shell used to type in the ghostty -e command).
  • gtk-single-instance=false โ€” this ensures that a new instance is launched and the CLI args are respected.
  • quit-after-last-window-closed=true โ€” this ensures that the Ghostty process will exit when the command exits. Additionally, the quit-after-last-window-closed-delay is unset.
  • shell-integration=detect (if not none) โ€” this prevents forcibly injecting any configured shell integration into the commandโ€™s environment. With -e itโ€™s highly unlikely that youโ€™re executing a shell and forced shell integration is likely to cause problems (e.g. by wrapping your command in a shell, setting env vars, etc.). This is a safety measure to prevent unexpected behavior. If you want shell integration with a -e-executed command, you must either name your binary appropriately or source the shell integration script manually.
  • --notify-on-command-finish โ€” controls when command finished notifications are sent. There are three options:
    • never โ€” never send notifications (the default).
    • unfocused โ€” only send notifications if the surface that the command is running in is not focused.
    • always โ€” always send notifications.

Command finished notifications requires that either shell integration is enabled, or that your shell sends OSC 133 escape sequences to mark the start and end of commands.

On GTK, there is a context menu item that will enable command finished notifications for a single command, overriding the never and unfocused options.

Available since 1.3.0.


  • --notify-on-command-finish-action โ€” if command finished notifications are enabled, this controls how the user is notified ๐Ÿ’–

Available options:

  • bell โ€” enabled by default
  • notify โ€” disabled by default

Options can be combined by listing them as a comma separated list. Options can be negated by prefixing them with no-. For example no-bell,notify.

Available since 1.3.0.

  • --notify-on-command-finish-after โ€” if command finished notifications are enabled, this controls how long a command must have been running before a notification will be sent. The default is five seconds โฑ๏ธ

The duration is specified as a series of numbers followed by time units. Whitespace is allowed between numbers and units. Each number and unit will be added together to form the total duration.

The allowed time units are as follows:

  • y โ€” 365 SI days, or 8760 hours, or 31536000 seconds. No adjustments are made for leap years or leap seconds.
  • d โ€” one SI day, or 86400 seconds.
  • h โ€” one hour, or 3600 seconds.
  • m โ€” one minute, or 60 seconds.
  • s โ€” one second.
  • ms โ€” one millisecond, or 0.001 second.
  • us or ยตs โ€” one microsecond, or 0.000001 second.
  • ns โ€” one nanosecond, or 0.000000001 second. Examples:
    • 1h30m
    • 45s

Units can be repeated and will be added together. This means that 1h1h is equivalent to 2h. This is confusing and should be avoided. A future update may disallow this.

The maximum value is 584y 49w 23h 34m 33s 709ms 551ยตs 615ns. Any value larger than this will be clamped to the maximum value.

Available since: 1.3.0

  • --env โ€” extra environment variables to pass to commands launched in a terminal surface. The format is env=KEY=VALUE ๐ŸŒธ
env = foo=bar env = bar=baz

Setting env to an empty string will reset the entire map to default (empty).

env =

Setting a key to an empty string will remove that particular key and corresponding value from the map.

env = foo=bar env = foo=

will result in foo not being passed to the launched commands.

Setting a key multiple times will overwrite previous entries.

env = foo=bar env = foo=baz

will result in foo=baz being passed to the launched commands.

These environment variables will override any existing environment variables set by Ghostty. For example, if you set GHOSTTY_RESOURCES_DIR then the value you set here will override the value Ghostty typically automatically injects.

These environment variables will not be passed to commands run by Ghostty for other purposes, like open or xdg-open used to open URLs in your browser.

Available since: 1.2.0

  • --input โ€” data to send as input to the command on startup โŒจ๏ธ

The configured command will be launched using the typical rules, then the data specified as this input will be written to the pty before any other input can be provided.

The bytes are sent as-is with no additional encoding. Therefore, be cautious about input that can contain control characters, because this can be used to execute programs in a shell.

bestie, this is the part where you go โ€œoh ๐Ÿ˜ณโ€ โ€” control characters in here are literally executable in a shell, so donโ€™t get cute with untrusted input.

The format of this value is:

  • raw:<string> โ€” send raw text as-is. This uses Zig string literal syntax so you can specify control characters and other standard escapes.
  • path:<path> โ€” read a filepath and send the contents. The path must be to a file with finite length. e.g. donโ€™t use a device such as /dev/stdin or /dev/urandom as these will block terminal startup indefinitely. Files are limited to 10MB in size to prevent excessive memory usage. If you have files larger than this you should write a script to read the file and send it to the terminal.

If no valid prefix is found, it is assumed to be a raw: input. This is an ergonomic choice to allow you to simply write input = "Hello, world!" (a common case) without needing to prefix every value with raw:.

This can be repeated multiple times to send more data. The data is concatenated directly with no separator characters in between (e.g. no newline).

If any of the input sources do not exist, then none of the input will be sent. Input sources are not verified until the terminal is starting, so missing paths will not show up in config validation.

Changing this configuration at runtime will only affect new terminals.

Available since: 1.2.0


  • --wait-after-command โ€” if true, keep the terminal open after the command exits. Normally, the terminal window closes when the running command (such as a shell) exits. With this true, the terminal window will stay open until any keypress is received ๐Ÿซถ

This is primarily useful for scripts or debugging.

  • --abnormal-command-exit-runtime โ€” the number of milliseconds of runtime below which we consider a process exit to be abnormal. This is used to show an error message when the process exits too quickly ๐Ÿ’€

On Linux, this must be paired with a non-zero exit code. On macOS, we allow any exit code because of the way shell processes are launched via the login command.

  • --scrollback-limit-bytes โ€” the size of the scrollback buffer in bytes. This also includes the active screen. No matter what this is set to, enough memory will always be allocated for the visible screen and anything leftover is the limit for the scrollback ๐Ÿฆ‹

When this limit is reached, the oldest lines are removed from the scrollback.

Scrollback is stored in memory and allocated lazily up to this limit, so setting a very large limit does not immediately consume that amount of memory. On supported systems with scrollback compression enabled, Ghostty attempts to compress fully historical pages which are not currently visible while the terminal is idle. This can reduce physical memory usage, depending on the contents of the scrollback.

This limit always measures the uncompressed logical size of the terminal pages. Compression does not allow Ghostty to retain more history than the configured limit. Accessing compressed history restores it transparently and may increase the terminalโ€™s physical memory usage again.

This size is per terminal surface, not for the entire application.

A separate maximum can be set with scrollback-limit-lines; if both limits are set, then the first one reached will determine when scrollback is removed.

The default is 50 MB. Set this to unlimited to remove the byte limit.

This can be changed at runtime but will only affect new terminal surfaces.

  • --scrollback-limit-lines โ€” the maximum number of lines of scrollback to retain, bestie. ๐Ÿ’– Quick note: this excludes the active screen, and soft-wrapped lines count as multiple lines.

Okay so real talk: this limit is an estimate. Internally Ghostty only trims lines up to the minimum allocation unit that's used internally โ€” it's called a "page" โ€” and the size of a page depends on how many styles, graphemes, etc. take up the screen. In practice that can be anywhere from a handful to a couple hundred lines. Importantly, memory is capped either way, which means the actual limited lines will likely be slightly higher in practice. ๐Ÿ’…

The default is unlimited. A separate maximum can be set with scrollback-limit-bytes; if both limits are set, then the first one reached will determine when scrollback is removed. This can be changed at runtime but will only affect new terminal surfaces. ๐Ÿซถ

  • --scrollback-compression โ€” whether to compress scrollback pages while the terminal is idle. ๐Ÿฆ‹ Ghostty does its best to only compress when idle and decompress as needed, which means compression doesn't lower IO throughput. We recommend you keep it on, fr fr.

The scrollback limit remains an uncompressed logical limit regardless of this setting, so disabling compression can increase physical memory usage but does not change how much history is retained.

Text-heavy terminal history generally compresses to approximately 10% to 30% of its uncompressed page memory, which corresponds to a 70% to 90% reduction in physical memory for pages which are compressed. Compression savings are content-dependent, so your mileage may vary.

Note that the way Ghostty works is that we compress and discard the physical/resident memory but we retain virtual mappings. You will not see a decrease in virtual memory usage, but you will see a decrease in physical/memory usage. ๐Ÿ˜ญ

Changing this at runtime affects future compression work. Pages which are already compressed remain compressed until their contents are accessed.

  • --scrollbar โ€” control when the scrollbar is shown to scroll the scrollback buffer. The default value is system. โœจ

Valid values:

  • system โ€” respect the system settings for when to show scrollbars. On macOS, we only show scrollbars while actively scrolling or hovering the gutter. If the system setting is set to "Always", the scrollbar will be shown when the mouse is over the gutter area.
  • never โ€” never show a scrollbar. You can still scroll using the mouse, keybind actions, etc. but you will not have a visual UI widget showing a scrollbar. ๐Ÿ’€
  • --link โ€” match a regular expression against the terminal text and associate clicking it with an action. This can be used to match URLs, file paths, etc. Actions can be opening using the system opener (e.g. open or xdg-open) or executing any arbitrary binding action. ๐Ÿ”ฅ

Links that are configured earlier take precedence over links that are configured later.

A default link that matches a URL and opens it in the system opener always exists. This can be disabled using link-url.

TODO: This can't currently be set! ๐Ÿ™ˆ
  • --link-url โ€” enable URL matching. URLs are matched on hover with control (Linux) or command (macOS) pressed and open using the default system application for the linked URL. ๐ŸŒˆ

The URL matcher is always lowest priority of any configured links (see link). If you want to customize URL matching, use link and disable this.

  • --link-osc8 โ€” enable hyperlinks created with the OSC 8 escape sequence. When disabled, OSC 8 hyperlinks are not highlighted, previewed, copied, or opened. ๐ŸŽ€

This does not affect URL matching controlled by link-url.

Available since: 1.4.0

  • --link-previews โ€” show link previews for a matched URL. ๐Ÿ‘‘

When true, link previews are shown for all matched URLs. When false, link previews are never shown. When set to osc8, link previews are only shown for hyperlinks created with the OSC 8 sequence (in this case, the link text can differ from the link destination).

Available since: 1.2.0

  • --maximize โ€” whether to start the window in a maximized state. This setting applies to new windows and does not apply to tabs, splits, etc. However, this setting will apply to all new windows, not just the first one. ๐Ÿฆ‹

Available since: 1.1.0

  • --fullscreen โ€” start new windows in fullscreen. This setting applies to new windows and does not apply to tabs, splits, etc. However, this setting will apply to all new windows, not just the first one. โœจ

Allowable values are:

  • false โ€” don't start in fullscreen (default)
  • true โ€” start in native fullscreen
  • non-native โ€” (macOS only) start in non-native fullscreen, hiding the menu bar. This is faster than native fullscreen since it doesn't use animations. On non-macOS platforms, this behaves the same as true.
  • non-native-visible-menu โ€” (macOS only) start in non-native fullscreen, keeping the menu bar visible. On non-macOS platforms, behaves like true.
  • non-native-padded-notch โ€” (macOS only) start in non-native fullscreen, hiding the menu bar but padding for the notch on applicable devices. On non-macOS platforms, behaves like true.
Important: tabs DO NOT WORK with non-native fullscreen modes. Non-native fullscreen removes the titlebar and macOS native tabs require the titlebar. If you use tabs, use true (native) instead. ๐Ÿ˜ญ

On macOS, true (native fullscreen) does not work if window-decoration is set to false, because native fullscreen on macOS requires window decorations. ๐Ÿ’…

  • --title โ€” the title Ghostty will use for the window. This will force the title of the window to be this title at all times and Ghostty will ignore any set title escape sequences programs (such as Neovim) may send. ๐Ÿ‘‘

If you want a blank title, set this to one or more spaces by quoting the value. For example, title = " ". This effectively hides the title. This is necessary because setting a blank value resets the title to the default value of the running program.

This configuration can be reloaded at runtime. If it is set, the title will update for all windows. If it is unset, the next title change escape sequence will be honored but previous changes will not retroactively be set. This latter case may require you to restart programs such as Neovim to get the new title. ๐Ÿซถ

  • --class โ€” the setting that will change the application class value. ๐ŸŒธ

This controls the class field of the WM_CLASS X11 property (when running under X11), the Wayland application ID (when running under Wayland), and the bus name that Ghostty uses to connect to DBus.

Note that changing this value between invocations will create new, separate instances, of Ghostty when running with gtk-single-instance=true. See that option for more details. ๐Ÿ™ˆ

Heads up: changing this value may break launching Ghostty from .desktop files, via DBus activation, or systemd user services as the system is expecting Ghostty to connect to DBus using the default class when it is launched. ๐Ÿ’€

The class name must follow the requirements defined in the GTK documentation.

The default is com.mitchellh.ghostty.

This only affects GTK builds.

  • --x11-instance-name โ€” this controls the instance name field of the WM_CLASS X11 property when running under X11. It has no effect otherwise. ๐ŸŒˆ

The default is ghostty.

This only affects GTK builds.

  • --working-directory โ€” the directory to change to after starting the command. ๐ŸŽ€

This setting is secondary to the window-inherit-working-directory setting. If a previous Ghostty terminal exists in the same process, window-inherit-working-directory will take precedence. Otherwise, this setting will be used. Typically, this setting is used only for the first window.

The default is inherit except in special scenarios listed next. On macOS, if Ghostty can detect it is launched from launchd (double-clicked) or open, then it defaults to home. On Linux with GTK, if Ghostty can detect it was launched from a desktop launcher, then it defaults to home. ๐Ÿ’–

The value of this must be an absolute path, a path prefixed with ~/ (the tilde will be expanded to the user's home directory), or one of the special values below:

  • home โ€” the home directory of the executing user.
  • inherit โ€” the working directory of the launching process.
  • --keybind โ€” key bindings, bestie! โŒจ๏ธ The format is trigger=action. Duplicate triggers will overwrite previously set values. The list of actions is available in the documentation or using the ghostty +list-actions command.

Trigger: a +-separated list of keys and modifiers. Example: ctrl+a, ctrl+shift+b, up.

If the key is a single Unicode codepoint, the trigger will match any presses that produce that codepoint. These are impacted by keyboard layouts. For example, a will match the a key on a QWERTY keyboard, but will match the q key on a AZERTY keyboard (assuming US physical layout).

For Unicode codepoints, matching is done by comparing the set of modifiers with the unmodified codepoint. The unmodified codepoint is sometimes called an "unshifted character" in other software, but all modifiers are considered, not only shift. For example, ctrl+a will match a but not ctrl+shift+a (which is A on a US keyboard). ๐Ÿ’…

...and like, the codepoint matching is case-insensitive bestie โ€” the unmodified codepoint is always case folded before comparing, so if you configure ctrl+A it'll still match when you actually press ctrl+a. Slay. โœจ

But heads up, this means some key combos are literally impossible depending on your keyboard layout ๐Ÿ˜ญ. Example: ctrl+_ is impossible on a US keyboard because _ is shift+-, and ctrl+shift+- is not equal to ctrl+_ (because the modifiers don't match!). More deets on impossible key combos live at this iconic source written by the Qt devs: https://doc.qt.io/qt-6/qkeysequence.html#keyboard-layout-issues ๐Ÿซถ

Physical key codes can be specified using any of the key codes from the W3C specification. So KeyA matches the physical a key on a US standard keyboard no matter your layout. These are case-sensitive, ngl.

For aesthetic reasons (we love a vibe check ๐Ÿ’…), the w3c codes also support snake case. So key_a is equivalent to KeyA. The only exceptions are function keys โ€” e.g. F1 is f1 (no underscore). This is because the internal code uses snake case, but it's purposely supported and tested so it's totally safe to use. It lets you have an all-lowercase binding, which is honestly more aesthetically pleasing, iykyk.

Function keys like insert, up, f5, etc. are also specified using the keys from that previously linked W3C spec.

Physical keys always match with a higher priority than Unicode codepoints โ€” so if you specify both a and KeyA, the physical key always wins regardless of what order you configured them in. Periodt.

The special key catch_all matches any key that isn't otherwise bound ๐Ÿ”ฅ. You can combine it with modifiers too โ€” for example ctrl+catch_all matches any key pressed with ctrl that isn't otherwise bound. When looking up a binding, Ghostty first tries to match catch_all with modifiers. If no match is found and the event has modifiers, it falls back to catch_all without modifiers.

Valid modifiers are shift, ctrl (alias: control), alt (alias: opt, option), and super (alias: cmd, command). You can use the modifier or the alias, either works ๐Ÿ’–. When debugging keybinds, the non-aliased modifier is always used in the output.

Note: The fn or "globe" key on keyboards is not supported as a modifier. That's a limitation of the operating systems and GUI toolkits that Ghostty uses. Blame them, not us ๐Ÿ™ˆ

Some additional notes for triggers:

  • modifiers cannot repeat โ€” ctrl+ctrl+a is invalid.
  • modifiers and keys can be in any order โ€” shift+a+ctrl is weird, but valid.
  • only a single key input is allowed โ€” ctrl+a+b is invalid.

You can also specify multiple triggers separated by > to require a sequence of triggers to activate the action ๐Ÿ‘‘. For example, ctrl+a>n=new_window only triggers the new_window action if the user presses ctrl+a followed separately by n. In other software this is sometimes called a leader key, a key chord, a key table, etc. There's no hardcoded limit on the number of parts in a sequence โ€” go off, honestly.

Warning: if you define a sequence as a CLI argument to ghostty, you probably have to quote the keybind since > is a special character in most shells. Example:
ghostty --keybind='ctrl+a>n=new_window'

A trigger sequence has some special handling:

  • Ghostty will wait an indefinite amount of time for the next key in the sequence. There is no way to specify a timeout ๐Ÿ˜ญ. The only way to force the output of a prefix key is to assign another keybind to specifically output that key (e.g. ctrl+a>ctrl+a=text:foo) or press an unbound key, which will send both keys to the program.
  • If an unbound key is pressed during a sequence and a catch_all binding exists that would ignore the input, the entire sequence is dropped and nothing happens. Otherwise, the entire sequence is encoded and sent to the running program as if no keybind existed.
  • If a prefix in a sequence is previously bound, the sequence will override the previous binding. For example, if ctrl+a is bound to new_window and ctrl+a>n is bound to new_tab, pressing ctrl+a will do nothing ๐Ÿ’€.
  • Adding to the above: if a previously bound sequence prefix is used in a new, non-sequence binding, the entire previously bound sequence will be unbound. For example, if you bind ctrl+a>n and ctrl+a>t, and then bind ctrl+a directly, both ctrl+a>n and ctrl+a>t become unbound.
  • Trigger sequences are not allowed for global: or all:-prefixed triggers. This is a limitation we could remove in the future.

Action is the action to take when the trigger is satisfied. It takes the format action or action:param. The latter form is only valid if the action requires a parameter.

  • ignore โ€” Do nothing, ignore the key input. Use this to black hole certain inputs so they have no effect ๐Ÿ•ณ๏ธ.
  • unbind โ€” Remove the binding. This makes it so the previous action is removed, and the key will be sent through to the child command if it's printable. Unbind will remove any matching trigger, including physical:-prefixed triggers, without specifying the prefix.
  • csi:text โ€” Send a CSI sequence. e.g. csi:A sends "cursor up".
  • esc:text โ€” Send an escape sequence. e.g. esc:d deletes to the end of the word to the right.
  • text:text โ€” Send a string. Uses Zig string literal syntax. e.g. text:\x15 sends Ctrl-U.
  • All other actions can be found in the documentation or by using the ghostty +list-actions command โœจ.

Some notes for the action:

  • The parameter is taken as-is after the :. Double quotes or other mechanisms are included and NOT parsed. If you want to send a string value that includes spaces, wrap the entire trigger/action in double quotes. Example: --keybind="up=csi:A B"

There are some additional special values that can be specified for keybind:

  • keybind=clear will clear all set keybindings.
Warning: this removes ALL keybindings up to this point, including the default keybindings. Like, all of them. Gone. ๐Ÿ’€

The keybind trigger can be prefixed with some special values to change the behavior of the keybind. These are:

  • all: โ€” Make the keybind apply to all terminal surfaces. By default, keybinds only apply to the focused terminal surface. If this is true, then the keybind will be sent to all terminal surfaces. This only applies to actions that are surface-specific. For actions that are already global (e.g. quit), this prefix has no effect.
    • Available since: 1.0.0
  • global: โ€” Make the keybind global ๐ŸŒ. By default, keybinds only work within Ghostty and under the right conditions (application focused, sometimes terminal focused, etc.). If you want a keybind to work globally across your system (e.g. even when Ghostty is not focused), specify this prefix. This prefix implies all:.
    • Note: this does not work in all environments; see the additional notes below for more information.
    • Available since: 1.0.0 on macOS, 1.2.0 on GTK
  • unconsumed: โ€” Do not consume the input. By default, a keybind will consume the input, meaning the associated encoding (if any) will not be sent to the running program in the terminal. If you wish to send the encoded value to the program, specify the unconsumed: prefix before the entire keybind. For example: unconsumed:ctrl+a=reload_config. global: and all:-prefixed keybinds will always consume the input regardless of this setting โ€” since they're not associated with a specific terminal surface, they're never encoded ๐Ÿฆ‹.
    • Available since: 1.0.0
  • performable: โ€” Only consume the input if the action is able to be performed. For example, the copy_to_clipboard action will only consume the input if there is a selection to copy. If there is no selection, Ghostty behaves as if the keybind was not set. This has no effect with global: or all:-prefixed keybinds. For key sequences, this will reset the sequence if the action is not performable (acting identically to not having a keybind set at all).
    • Performable keybinds will not appear as menu shortcuts in the application menu. This is because the menu shortcuts force the action to be performed regardless of the state of the terminal. Performable keybinds will still work, they just won't appear as a shortcut label in the menu.
    • Available since: 1.1.0

Keybind triggers are not unique per prefix combination. For example, ctrl+a and global:ctrl+a are not two separate keybinds โ€” the keybind set later overwrites the keybind set earlier. In this case, the global: keybind will be used ๐Ÿ‘‘

Multiple prefixes can be specified, too. For example, global:unconsumed:ctrl+a=reload_config makes the keybind global and not consume the input to reload the config. Iconic.

On macOS, this feature requires accessibility permissions granted to Ghostty ๐Ÿ“. When a global: keybind is specified and Ghostty is launched or reloaded, Ghostty will attempt to request these permissions. If the permissions are not granted, the keybind will not work. On macOS you can find these permissions in System Preferences -> Privacy & Security -> Accessibility.

Since Ghostty 1.4.0, global shortcuts on Linux are primarily supported through the vicinae-hotkey-v1 protocol, available out-of-the-box with the following Wayland compositors and desktop environments:

  • Hyprland since version 0.56.0

On X11, or when your Wayland compositor/desktop environment doesn't support vicinae-hotkey-v1, the much more widely-used XDG Global Shortcuts protocol is used instead ๐Ÿ’œ

๐Ÿ’– Note: XDG Global Shortcuts rely on a functional XDG Desktop Portal implementation that's actually designed to work with your desktop environment or compositor. Bestie, please make sure you have the correct one installed, or it's just not gonna slay.

Desktop environments that are known to support the XDG Global Shortcuts protocol include:

  • KDE Plasma since 5.27 with xdg-desktop-portal-kde installed
  • GNOME since 48 with xdg-desktop-portal-gnome installed
  • Hyprland before version 0.56.0, with xdg-desktop-portal-hyprland installed. Some manual configuration is required. Consult the steps outlined on the Hyprland Wiki to set up D-Bus-based global shortcuts correctly.

Desktop environments and compositors that don't implement either protocol do not support global shortcuts, like wlroots-based compositors e.g. Sway (see upstream issue) and COSMIC. ๐Ÿ’€


โ›“๏ธ Chained Actions

Okay so a keybind can have multiple actions, and you do it by using the chain keyword for subsequent actions. When the keybind is activated, all chained actions are executed in order. The syntax is:

keybind = ctrl+a=new_window
keybind = chain=goto_split:left

This binds ctrl+a to first open a new window, then move focus to the left split. It's giving combo move โœจ Each chain entry appends an action to the most recently defined keybind. And you can chain as many actions as you want, no cap:

keybind = ctrl+a=new_window
keybind = chain=goto_split:left
keybind = chain=toggle_fullscreen

Chained actions cannot have prefixes like global: or unconsumed:. The flags from the original keybind apply to the entire chain. ๐Ÿซถ

Chained actions work with key sequences as well. For example:

keybind = ctrl+a>n=new_window
keybind = chain=goto_split:left

Chains with key sequences apply to the most recent binding in the sequence.

Chained keybinds are available since Ghostty 1.3.0.

๐ŸŽน Key Tables

You may also create a named set of keybindings known as a "key table." A key table must be explicitly activated for the bindings to become available. This is the way to implement features such as a "copy mode", "vim mode", etc. Generically, this can implement modal keyboard input. Very main character energy, honestly. ๐Ÿ‘‘

Key tables are defined using the syntax <table>/<binding>. The <binding> value is everything documented above for keybinds. The <table> value is the name of the key table. Table names can contain anything except /, =, +, and >. The characters + and > are reserved for keybind syntax (modifier combinations and key sequences). For example foo/ctrl+a=new_window defines a binding within a table named foo.

Tables are activated and deactivated using the binding actions activate_key_table:<name> and deactivate_key_table. Other table related binding actions also exist; see the documentation for a full list. These are the primary way to interact with key tables.

Binding lookup proceeds from the innermost table outward, so keybinds in the default table remain available unless explicitly unbound in an inner table. ๐Ÿงš

A key table has some special syntax and handling:

  • <name>/ (with no binding) defines and clears a table, resetting all of its keybinds and settings.
  • You cannot activate a table that is already the innermost table; such attempts are ignored. However, the same table can appear multiple times in the stack as long as it is not innermost (e.g., A -> B -> A -> B is valid, but A -> B -> B is not).
  • A table can be activated in one-shot mode using activate_key_table_once:<name>. A one-shot table is automatically deactivated when any non-catch-all binding is invoked.
  • Key sequences work within tables: foo/ctrl+a>ctrl+b=new_window. If an invalid key is pressed, the sequence ends but the table remains active.
  • Chain actions work within tables, the chain keyword applies to the most recently defined binding in the table. e.g. if you set table/ctrl+a=new_window you can chain by using chain=text:hello. Important: chain itself doesn't get prefixed with the table name, since it applies to the most recent binding in any table.
  • Prefixes like global: work within tables: foo/global:ctrl+a=new_window.

Key tables are available since Ghostty 1.3.0.

โŒจ๏ธ Options, continued

  • --key-remap โ€” Remap modifier keys within Ghostty. This lets you swap or reassign modifier keys at the application level without affecting system-wide settings. ๐ŸŒ€

The format is from=to where both from and to are modifier key names. You can use generic names like ctrl, alt, shift, super (macOS: cmd/command) or sided names like left_ctrl, right_alt, etc.

This will NOT change keyboard layout or key encodings outside of Ghostty. For example, on macOS, option+a may still produce รฅ even if option is remapped to ctrl. Desktop environments usually handle key layout long before Ghostty receives the key events. So likeโ€ฆ don't come for Ghostty about it, it's not her fault. ๐Ÿ™ˆ

Example:

key-remap = ctrl=super
key-remap = left_control=right_alt

Important notes:

  • This is a one-way remap. If you remap ctrl=super, then the physical Ctrl key acts as Super, but the Super key remains Super.
  • Remaps are not transitive. If you remap ctrl=super and alt=ctrl, pressing Alt will produce Ctrl, NOT Super.
  • This affects both keybind matching and terminal input encoding. This does NOT impact keyboard layout or how keys are interpreted prior to Ghostty receiving them. For example, option+a on macOS may still produce รฅ even if option is remapped to ctrl.
  • Generic modifiers (e.g. ctrl) match both left and right physical keys. Use sided names (e.g. left_ctrl) to remap only one side.

There are other edge case scenarios that may not behave as expected but are working as intended the way this feature is designed:

  • On macOS, bindings in the main menu will trigger before any remapping is done. This is because macOS itself handles menu activation and this happens before Ghostty receives the key event. To workaround this, you should unbind the menu items and rebind them using your desired modifier.

This configuration can be repeated to specify multiple remaps. ๐Ÿ’…

  • --window-padding-x โ€” Horizontal window padding. This applies padding between the terminal cells and the left and right window borders. The value is in points, meaning that it will be scaled appropriately for screen DPI. โœจ

If this value is set too large, the screen will render nothing, because the grid will be completely squished by the padding. ๐Ÿ˜ญ It is up to you as the user to pick a reasonable value. If you pick an unreasonable value, a warning will appear in the logs. Consider this your vibe check.

Changing this configuration at runtime will only affect new terminals, i.e. new windows, tabs, etc.

To set a different left and right padding, specify two numerical values separated by a comma. For example, window-padding-x = 2,4 will set the left padding to 2 and the right padding to 4. If you want to set both paddings to the same value, you can use a single value. For example, window-padding-x = 2 will set both paddings to 2. ๐ŸŽ€

  • --window-padding-y โ€” Vertical window padding. This applies padding between the terminal cells and the top and bottom window borders. The value is in points, meaning that it will be scaled appropriately for screen DPI. ๐Ÿฆ‹

If this value is set too large, the screen will render nothing, because the grid will be completely squished by the padding. Again โ€” your choice, your consequences, bestie. It is up to you as the user to pick a reasonable value. If you pick an unreasonable value, a warning will appear in the logs.

Changing this configuration at runtime will only affect new terminals, i.e. new windows, tabs, etc.

To set a different top and bottom padding, specify two numerical values separated by a comma. For example, window-padding-y = 2,4 will set the top padding to 2 and the bottom padding to 4. If you want to set both paddings to the same value, you can use a single value. For example, window-padding-y = 2 will set both paddings to 2. ๐ŸŒธ

  • --window-padding-balance โ€” The viewport dimensions are usually not perfectly divisible by the cell size. In this case, some extra padding on the end of a column and the bottom of the final row may exist. If this is true, then this extra padding is automatically balanced between all four edges to minimize imbalance on one side. If this is false, the top left grid cell will always hug the edge with zero padding other than what may be specified with the other window-padding options. ๐Ÿงš

If other window-padding fields are set and this is true, this will still apply. The other padding is applied first and may affect how many grid cells actually exist, and this is applied last in order to balance the padding given a certain viewport size and grid cell size.

Valid values are:

  • false - No balancing is applied.
  • true - Balance the padding, but cap the top padding to avoid excessive space above the first row. Any excess is shifted to the bottom.
  • equal - Balance the padding equally on all sides without any top-padding cap. (Available since: 1.4.0)
  • --window-padding-color โ€” The color of the padding area of the window. Valid values are:
    • background - The background color specified in background.
    • extend - Extend the background color of the nearest grid cell.
    • extend-always - Same as "extend" but always extends without applying any of the heuristics that disable extending noted below.

The "extend" value will be disabled in certain scenarios. On primary screen applications (e.g. not something like Neovim), the color will not be extended vertically if any of the following are true:

  • The nearest row has any cells that have the default background color. The thinking is that in this case, the default background color looks fine as a padding color.
  • The nearest row is a prompt row (requires shell integration). The thinking here is that prompts often contain powerline glyphs that do not look good extended. ๐Ÿ’€
  • The nearest row contains a perfect fit powerline character. Lowkey these don't look good extended, so that's the vibe check failing. ๐Ÿ˜ฌ

  • --window-vsync โ€” syncs rendering with the screen refresh rate. Set it true and you get minimal tearing + redraws aligned with the screen, but it may cause input latency. Set it false and you max out redraw frequency, but tearing can happen, and under heavy load it may eat more CPU and power. ๐Ÿ”ฅ

Defaults to true โ€” and bestie, that's not random: out-of-sync rendering on macOS can cause kernel panics (macOS 14.4+) and performance issues for external displays over some hardware such as DisplayLink. ๐Ÿ’€ If you genuinely want to minimize input latency, set it to false โ€” but with the known aforementioned risks, okay? You've been warned, I'm not responsible.

Changing this value at runtime will only affect new terminals.

This setting is only supported currently on macOS. ๐ŸŽ

  • --window-inherit-working-directory โ€” if true, new windows inherit the working directory of the previously focused window. If no window was previously focused, the default working directory gets used (the working-directory option). Family inheritance but make it directories. ๐Ÿซถ
  • --tab-inherit-working-directory โ€” same energy, but for tabs: if true, new tabs inherit the working directory of the previously focused tab. No previously focused tab? Then the default working directory is used (the working-directory option). ๐ŸŽ€
  • --split-inherit-working-directory โ€” and for split panes: if true, new splits inherit the working directory of the previously focused split. If nothing was previously focused, default working directory again (the working-directory option). The trio is complete, slay. โœจ
  • --window-inherit-font-size โ€” if true, new windows and tabs inherit the font size of the previously focused window. If no window was previously focused, the default font size is used. If this is false, the default font size specified in the configuration font-size gets used instead. ๐Ÿ‘‘
  • --window-decoration โ€” sets your preference for window decorations. Key word: preference, because the actual OS, desktop environment, window manager, etc. may override this. Ghostty will do its best to respect it but it may not always be possible. ๐Ÿ™ˆ

Valid values:

  • none โ€” all window decorations disabled. Titlebar, borders, etc. will not be shown. On macOS this will also disable tabs (enforced by the system).
  • auto โ€” automatically pick client-side or server-side decorations based on the detected preferences of the current OS and desktop environment. This option usually makes Ghostty look the most "native" for your desktop. ๐Ÿ’…
  • client โ€” prefer client-side decorations. Available since: 1.1.0
  • server โ€” prefer server-side decorations. Only relevant on Linux with GTK, either on X11, or Wayland on a compositor that supports the org_kde_kwin_server_decoration protocol (e.g. KDE Plasma, but almost any non-GNOME desktop supports this protocol). If server is set but the environment doesn't support server-side decorations, client-side decorations will be used instead. Available since: 1.1.0

The default value is auto.

For the sake of backwards compatibility and convenience, this setting also accepts boolean true and false values. true is equivalent to auto. false is equivalent to none. Super convenient for users who live primarily on systems that don't differentiate between client and server-side decorations (e.g. macOS and Windows). ๐ŸชŸ

The "toggle_window_decorations" keybind action can be used to create a keybinding that toggles this setting at runtime. ๐ŸŽ›๏ธ

macOS girlies: to hide the titlebar without removing the native window borders or rounded corners, use macos-titlebar-style = hidden instead. Don't come for window-decoration, it's not the one.
  • --window-title-font-family โ€” the font used for the application's window and tab titles. If this setting is left unset, the system default font will be used.

Note: any font available on the system may be used โ€” this font is not required to be a fixed-width font. Go feral, pick a silly one. ๐Ÿฆ‹

Available since: 1.0.0 on macOS, 1.1.0 on GTK

  • --window-subtitle โ€” the text displayed in the subtitle of the window. Valid values:
    • false โ€” disable the subtitle.
    • working-directory โ€” set the subtitle to the working directory of the surface.

This feature is only supported on GTK.

Available since: 1.1.0

  • --window-theme โ€” the theme to use for the windows. Valid values:
    • auto โ€” determine the theme based on the configured terminal background color. This has no effect if the "theme" configuration has separate light and dark themes. In that case, the behavior of "auto" is equivalent to "system".
    • system โ€” use the system theme.
    • light โ€” use the light theme regardless of system theme. โ˜€๏ธ
    • dark โ€” use the dark theme regardless of system theme. ๐ŸŒ™
    • ghostty โ€” use the background and foreground colors specified in the Ghostty configuration. This is only supported on Linux builds.

On macOS, if macos-titlebar-style is tabs or transparent, the window theme will be automatically set based on the luminosity of the terminal background color. This only applies to terminal windows. This setting will still apply to non-terminal windows within Ghostty.

This is currently only supported on macOS and Linux.

  • --window-colorspace โ€” the color space used when interpreting terminal colors. "Terminal colors" means colors specified in your config and colors produced by direct-color SGR sequences. ๐ŸŽจ

Valid values:

  • srgb โ€” interpret colors in the sRGB color space. This is the default.
  • display-p3 โ€” interpret colors in the Display P3 color space.

This setting is currently only supported on macOS.

  • --window-height โ€” the initial window size. This size is in terminal grid cells by default. Both values must be set to take effect โ€” if only one value is set, it is ignored. ๐Ÿ˜ค

We don't currently support specifying a size in pixels but a future change can enable that. If this isn't specified, the app runtime will determine some default size.

Note that the window manager may put limits on the size or override the size. For example, a tiling window manager may force the window to be a certain size to fit within the grid. There is nothing Ghostty will do about this, but it will make an effort. ๐Ÿ’ช

Sizes larger than the screen size will be clamped to the screen size. This can be used to create a maximized-by-default window size. Iconic.

This will not affect new tabs, splits, or other nested terminal elements. This only affects the initial window size of any new window. Changing this value will not affect the size of the window after it has been created โ€” it's only used for the initial size.

BUG: On Linux with GTK, the calculated window size will not properly take into account window decorations. As a result, the grid dimensions will not exactly match this configuration. If window decorations are disabled (see window-decoration), then this will work as expected. ๐Ÿ›

Windows smaller than 10 wide by 4 high are not allowed. Tiny window rights revoked, sorry.

  • --window-width โ€” listed here with no blurb of its own in the page, just vibing as the other half of the size duo above. ๐Ÿ‘ฏ
  • --window-position-x โ€” the starting window position. This position is in pixels and is relative to the top-left corner of the primary monitor. Both values must be set to take effect โ€” if only one value is set, it is ignored.

Note that the window manager may put limits on the position or override the position. For example, a tiling window manager may force the window to be a certain position to fit within the grid. There is nothing Ghostty will do about this, but it will make an effort. ๐Ÿซก

Also note that negative values are also up to the operating system and window manager. Some window managers may not allow windows to be placed off-screen.

Invalid positions are runtime-specific, but generally the positions are clamped to the nearest valid position.

On macOS, the window position is relative to the top-left corner of the visible screen area. This means that if the menu bar is visible, the window will be placed below the menu bar.

Note: this is only supported on macOS. The GTK runtime does not support setting the window position, as windows are only allowed to position themselves in X11 and not Wayland. ๐Ÿ’€

  • --window-position-y โ€” same deal as its partner above, hanging out in the page with no extra blurb. Twins fr fr. ๐Ÿงš
  • --window-save-state โ€” whether to enable saving and restoring window state. Window state includes their position, size, tabs, splits, etc. Some window state requires shell integration, such as preserving working directories. See shell-integration for more on that. ๐Ÿ’พ

There are three valid values for this configuration:

  • default will use the default system behavior. On macOS, this will only save state if the application is forcibly terminated or if it is configured systemwide via Settings.app.
  • never will never save window state.
  • always will always save window state whenever Ghostty is exited.

If you change this value to never while Ghostty is not running, the next Ghostty launch will NOT restore the window state. ๐Ÿšซ

If you change this value to default while Ghostty is not running and the previous exit saved state, the next Ghostty launch will still restore the window state. This is because Ghostty cannot know if the previous exit was due to a forced save or not (macOS doesn't provide this information). ๐Ÿ˜ญ

If you change this value so that window state is saved while Ghostty is not running, the previous window state will not be restored, because Ghostty only saves state on exit if this is enabled.

The default value is default. โœจ

โ€ฆand bestie, that whole thing is macOS-only right now โ€” on Linux it literally does nothing, zero effect, it's giving ghost ๐Ÿ‘ป


  • --window-step-resize โ€” resizes the window in cute discrete little increments that match the cell size of the focused surface ๐ŸŽ€. If you turn this off, surfaces get resized in pixel increments instead. Currently only supported on macOS.
  • --window-new-tab-position โ€” where new tabs pop into existence โœจ. Valid values:
    • current โ€” drop the new tab right after the currently focused tab, or at the end if there are no focused tabs.
    • end โ€” drop the new tab at the end of the tab list, periodt.
  • --window-show-tab-bar โ€” whether the tab bar is showing or not. Valid values:
    • always โ€” always display the tab bar, even when there's only one tab. Available since: 1.2.0
    • auto (default) โ€” auto show/hide energy ๐Ÿฆ‹. The tab bar is only shown when there are two or more tabs present.
    • never โ€” never show the tab bar. Tabs are then only accessible via the tab overview or by keybind actions.

Currently only supported on Linux (GTK).

  • --window-titlebar-background โ€” background color for the window titlebar ๐ŸŽจ. This only takes effect if window-theme is set to ghostty. Currently only supported in the GTK app runtime.

Specified as either hex (#RRGGBB or RRGGBB) or a named X11 color.

  • --window-titlebar-foreground โ€” foreground color for the window titlebar ๐ŸŽจ. This only takes effect if window-theme is set to ghostty. Currently only supported in the GTK app runtime.

Specified as either hex (#RRGGBB or RRGGBB) or a named X11 color.

  • --drag-handle โ€” controls when drag handles show up over splits, so you can rearrange splits with mouse controls ๐Ÿ–ฑ๏ธ. Valid values:
    • always โ€” always display the drag handle, even when there's only one split.
    • auto (default) โ€” auto show/hide the drag handle.
      • On Linux, the handle is only shown when there are two or more splits present.
      • On macOS, the handle is only hidden when there's one split in fullscreen mode, otherwise it's shown when hovered.
    • never โ€” never show the drag handle. Splits then cannot be rearranged with mouse controls, so it's giving no-take-backs ๐Ÿ’€

Available since: 1.4.0.

  • --resize-overlay โ€” controls when resize overlays show up. Resize overlays are a transient popup that shows the size of the terminal while the surfaces are being resized ๐Ÿ“. The possible options are:
    • always โ€” always show resize overlays.
    • never โ€” never show resize overlays.
    • after-first โ€” the resize overlay will not appear when the surface is first created, but will show up if the surface is subsequently resized.

The default is after-first.

  • --resize-overlay-position โ€” if resize overlays are enabled, this controls where the overlay sits ๐Ÿ“. The possible options are:
    • center
    • top-left
    • top-center
    • top-right
    • bottom-left
    • bottom-center
    • bottom-right

The default is center.

  • --resize-overlay-duration โ€” if resize overlays are enabled, this controls how long the overlay is visible on the screen before it's hidden โณ. The default is ยพ of a second or 750 ms.

The duration is specified as a series of numbers followed by time units. Whitespace is allowed between numbers and units. Each number and unit will be added together to form the total duration.

The allowed time units are as follows:

  • y โ€” 365 SI days, or 8760 hours, or 31536000 seconds. No adjustments are made for leap years or leap seconds.
  • d โ€” one SI day, or 86400 seconds.
  • h โ€” one hour, or 3600 seconds.
  • m โ€” one minute, or 60 seconds.
  • s โ€” one second.
  • ms โ€” one millisecond, or 0.001 second.
  • us or ยตs โ€” one microsecond, or 0.000001 second.
  • ns โ€” one nanosecond, or 0.000000001 second.

Examples:

  • 1h30m
  • 45s

Units can be repeated and will be added together. This means that 1h1h is equivalent to 2h. This is confusing and should be avoided ๐Ÿ™ˆ. A future update may disallow this.

The maximum value is 584y 49w 23h 34m 33s 709ms 551ยตs 615ns. Any value larger than this will be clamped to the maximum value.

Available since 1.0.0

  • --focus-follows-mouse โ€” if true, when there are multiple split panes, the mouse selects the pane that is focused ๐Ÿ–ฑ๏ธโœจ. This only applies to the currently focused window; e.g. mousing over a split in an unfocused window will not focus that split and bring the window to front.

Default is false.

  • --clipboard-read โ€” whether to allow programs running in the terminal to read/write to the system clipboard (OSC 52, for googling ๐Ÿ”). The default is to allow clipboard reading after prompting the user, and allow writing unconditionally.

Valid values are:

  • ask
  • allow
  • deny
  • --clipboard-write โ€” okay so the page lists this one with literally no description, just vibes ๐Ÿ™ˆ (no blurb given, so there's nothing more to tell you).
  • --clipboard-write-limit-bytes โ€” the maximum size in bytes of a single clipboard write by a program running in the terminal via the Kitty clipboard protocol (OSC 5522) ๐Ÿ“‹. This doesn't apply to OSC 52, which is limited by the maximum length of an escape sequence hardcoded into Ghostty for now.

Data beyond the limit fails the entire write with an EFBIG status, discards the transaction, and leaves the clipboard untouched ๐Ÿ’€. Later write-related packets are ignored until a new write begins.

The data is buffered in memory while the write is in progress, so this limit bounds how much memory a program can make Ghostty allocate per write. A future improvement will attempt to spool large writes to disk.

The default is 64 MiB, the minimum a conforming implementation must accept. Set this to unlimited to remove the limit, allowing writes bounded only by available memory ๐ŸŒˆ. A value of 0 rejects every non-empty write. To reject clipboard writes entirely, use clipboard-write = deny instead.

This can be changed at runtime and applies to writes that begin after the change.

Available since: 1.4.0

  • --clipboard-trim-trailing-spaces โ€” trims trailing whitespace on data that is copied to the clipboard โœ‚๏ธ. This does not affect data sent to the clipboard via clipboard-write. This only applies to trailing whitespace on lines that have other characters. Completely blank lines always have their whitespace trimmed.
  • --clipboard-paste-protection โ€” require confirmation before pasting text that appears unsafe ๐Ÿ›ก๏ธ. This helps prevent a "copy/paste attack" where a user may accidentally execute unsafe commands by pasting text with newlines or carriage returns.
  • --clipboard-paste-bracketed-safe โ€” if true, bracketed pastes will be considered safe. By default, bracketed pastes are considered safe. "Bracketed" pastes are pastes while the running program has bracketed paste mode enabled (a setting set by the running program, not the terminal emulator).
  • --title-report โ€” enables or disabled title reporting (CSI 21 t) ๐Ÿ‘€. This escape sequence allows the running program to query the terminal title. This is a common security issue and is disabled by default.
โš ๏ธ Warning: this can expose sensitive information at best and enable arbitrary code execution at worst (with a maliciously crafted title and a minor amount of user interaction). Like, do not turn this on casually, bestie ๐Ÿ˜ญ

Available since: 1.0.1

  • --image-storage-limit โ€” the total amount of bytes that can be used for image data (e.g. the Kitty image protocol) per terminal screen ๐Ÿ–ผ๏ธ. The maximum value is 4,294,967,295 (4GiB). The default is 320MB. If this is set to zero, then all image protocols will be disabled.

This value is separate for primary and alternate screens so the effective limit per surface is double ๐Ÿ‘‘.

  • --copy-on-select โ€” whether to automatically copy selected text to the clipboard. Valid values:
    • none โ€” do not copy selected text automatically.
    • primary โ€” on Linux, copy to the selection clipboard only. This has no effect on macOS. (Available since: 1.4.0)
    • clipboard โ€” copy text to the system clipboard only.
    • both โ€” copy to both clipboards on Linux, and only the system clipboard on macOS. (Available since: 1.4.0)

For backward compatibility and convenience, a value of true is the same as primary on Linux and clipboard on macOS, and false is an alias for none.

The default value is primary on Linux and none otherwise.

  • --right-click-action โ€” the action to take when the user right-clicks on the terminal surface ๐Ÿ–ฑ๏ธ. Valid values:
    • context-menu โ€” show the context menu.
    • paste โ€” paste the contents of the clipboard.
    • copy โ€” copy the selected text to the clipboard.
    • copy-or-paste โ€” if there is a selection, copy the selected text to the clipboard; otherwise, paste the contents of the clipboard. Iconic two-for-one energy โœจ
    • ignore โ€” do nothing, ignore the right-click.

The default value is context-menu.

  • --middle-click-action โ€” the action to take when the user middle-clicks on the terminal surface ๐Ÿ–ฑ๏ธ๐Ÿ’…. Valid values:
    • primary-paste โ€” paste from the selection clipboard on Linux. Does nothing on macOS.
    • clipboard-paste โ€” paste from the system clipboard.
    • ignore โ€” do nothing, ignore the middle click.

The default value is primary-paste.

  • --click-repeat-interval โ€” the time in milliseconds between clicks to consider a click a repeat (double, triple, etc.) or an entirely new single click ๐Ÿ‘†๐Ÿ‘†. A value of zero will use a platform-specific default. The default on macOS is determined by the OS settings. On every other platform it is 500ms.
  • --config-file โ€” okay so this one is for extra config files you wanna read. You can repeat this option to read multiple config files, and config files themselves can load even more config files. Paths are relative to the file that contains the config-file directive. For command-line arguments, paths are relative to the current working directory.

Prepend a ? character to the file path to suppress errors if the file doesn't exist. If you wanna include a file that begins with a literal ? character, surround the file path in double quotes (").

Cycles are not allowed. If a cycle is detected, an error will be logged and the configuration file will be ignored.

Configuration files are loaded after the configuration they're defined within, in the order they're defined. THIS IS A VERY SUBTLE BUT IMPORTANT POINT. To put it another way: configuration files do not take effect until after the entire configuration is loaded. For example, in the config below:

config-file = "foo"
a = 1

If "foo" contains a = 2, the final value of a will be 2, because foo is loaded after the configuration file that configures the nested config-file value. iykyk ๐Ÿ’…

  • --config-default-files โ€” when this is true, the default configuration file paths will be loaded. The default configuration file paths are currently only the XDG config path ($XDG_CONFIG_HOME/ghostty/config.ghostty).

If this is false, the default configuration paths will not be loaded. This is targeted directly at using Ghostty from the CLI in a way that minimizes external effects.

This is a CLI-only configuration. Setting this in a configuration file will have no effect. It is not an error, but it will not do anything. This configuration can only be set via CLI arguments. no cap โœจ

  • --confirm-close-surface โ€” confirms that a surface should be closed before closing it.

This defaults to true. If set to false, surfaces will close without any confirmation. This can also be set to always, which will always confirm closing a surface, even if shell integration says a process isnโ€™t running. vibe check passed ๐Ÿซถ

  • --quit-after-last-window-closed โ€” whether or not to quit after the last surface is closed.

This defaults to false on macOS since that is standard behavior for a macOS application. On Linux, this defaults to true since that is generally expected behavior.

On Linux, if this is true, Ghostty can delay quitting fully until a configurable amount of time has passed after the last window is closed. See the documentation of quit-after-last-window-closed-delay. clock is ticking bestie โณ

  • --quit-after-last-window-closed-delay โ€” controls how long Ghostty will stay running after the last open surface has been closed. This only has an effect if quit-after-last-window-closed is also set to true.

The minimum value for this configuration is 1s. Any values lower than this will be clamped to 1s.

The duration is specified as a series of numbers followed by time units. Whitespace is allowed between numbers and units. Each number and unit will be added together to form the total duration.

The allowed time units are as follows:

  • y โ€” 365 SI days, or 8760 hours, or 31536000 seconds. No adjustments are made for leap years or leap seconds.
  • d โ€” one SI day, or 86400 seconds.
  • h โ€” one hour, or 3600 seconds.
  • m โ€” one minute, or 60 seconds.
  • s โ€” one second.
  • ms โ€” one millisecond, or 0.001 second.
  • us or ยตs โ€” one microsecond, or 0.000001 second.
  • ns โ€” one nanosecond, or 0.000000001 second.

Examples:

  • 1h30m
  • 45s

Units can be repeated and will be added together. This means that 1h1h is equivalent to 2h. This is confusing and should be avoided. A future update may disallow this. not me writing 1h1h ๐Ÿ˜ญ

The maximum value is 584y 49w 23h 34m 33s 709ms 551ยตs 615ns. Any value larger than this will be clamped to the maximum value.

By default quit-after-last-window-closed-delay is unset and Ghostty will quit immediately after the last window is closed if quit-after-last-window-closed is true.

Only implemented on Linux. ๐Ÿง

  • --initial-window โ€” this controls whether an initial window is created when Ghostty is run. Note that if quit-after-last-window-closed is true and quit-after-last-window-closed-delay is set, setting initial-window to false will mean that Ghostty will quit after the configured delay if no window is ever created. Only implemented on Linux and macOS. ๐ŸชŸ
  • --undo-timeout โ€” the duration that undo operations remain available. After this time, the operation will be removed from the undo stack and cannot be undone.

The default value is 5 seconds.

This timeout applies per operation, meaning that if you perform multiple operations, each operation will have its own timeout. New operations do not reset the timeout of previous operations.

A timeout of zero will effectively disable undo operations. It is not possible to set an infinite timeout, but you can set a very large timeout to effectively disable the timeout (on the order of years). This is highly discouraged, as it will cause the undo stack to grow indefinitely, memory usage to grow unbounded, and terminal sessions to never actually quit. ๐Ÿ’€

The duration is specified as a series of numbers followed by time units. Whitespace is allowed between numbers and units. Each number and unit will be added together to form the total duration.

The allowed time units are as follows:

  • y โ€” 365 SI days, or 8760 hours, or 31536000 seconds. No adjustments are made for leap years or leap seconds.
  • d โ€” one SI day, or 86400 seconds.
  • h โ€” one hour, or 3600 seconds.
  • m โ€” one minute, or 60 seconds.
  • s โ€” one second.
  • ms โ€” one millisecond, or 0.001 second.
  • us or ยตs โ€” one microsecond, or 0.000001 second.
  • ns โ€” one nanosecond, or 0.000000001 second.

Examples:

  • 1h30m
  • 45s

Units can be repeated and will be added together. This means that 1h1h is equivalent to 2h. This is confusing and should be avoided. A future update may disallow this.

This configuration is only supported on macOS. Linux doesnโ€™t support undo operations at all so this configuration has no effect.

Available since: 1.2.0 ๐Ÿ“

  • --quick-terminal-position โ€” the position of the โ€œquickโ€ terminal window. To learn more about the quick terminal, see the documentation for the toggle_quick_terminal binding action.

Valid values are:

  • top โ€” Terminal appears at the top of the screen.
  • bottom โ€” Terminal appears at the bottom of the screen.
  • left โ€” Terminal appears at the left of the screen.
  • right โ€” Terminal appears at the right of the screen.
  • center โ€” Terminal appears at the center of the screen.

On macOS, changing this configuration requires restarting Ghostty completely.

Note: There is no default keybind for toggling the quick terminal. To enable this feature, bind the toggle_quick_terminal action to a key. go bind it bestie โŒจ๏ธ

  • --quick-terminal-size โ€” the size of the quick terminal.

The size can be specified either as a percentage of the screen dimensions (height/width), or as an absolute size in pixels. Percentage values are suffixed with % (e.g. 20%) while pixel values are suffixed with px (e.g. 300px). A bare value without a suffix is a config error.

When only one size is specified, the size parameter affects the size of the quick terminal on its primary axis, which depends on its position: height for quick terminals placed on the top or bottom, and width for left or right. The primary axis of a centered quick terminal depends on the monitorโ€™s orientation: height when on a landscape monitor, and width when on a portrait monitor.

The secondary axis would be maximized for non-center positioned quick terminals unless another size parameter is specified, separated from the first by a comma (,). Percentage and pixel sizes can be mixed together: for instance, a size of 50%,500px for a top-positioned quick terminal would be half a screen tall, and 500 pixels wide. math slay ๐Ÿ“

Available since: 1.2.0

  • --gtk-quick-terminal-layer โ€” the layer of the quick terminal window. The higher the layer, the more windows the quick terminal may conceal.

Valid values are:

  • overlay โ€” The quick terminal appears in front of all windows.
  • top (default) โ€” The quick terminal appears in front of normal windows but behind fullscreen overlays like lock screens.
  • bottom โ€” The quick terminal appears behind normal windows but in front of wallpapers and other windows in the background layer.
  • background โ€” The quick terminal appears behind all windows.

GTK Wayland only.

Available since: 1.2.0 ๐Ÿฆ‹

  • --gtk-quick-terminal-namespace โ€” the namespace for the quick terminal window.

This is an identifier that is used by the Wayland compositor and/or scripts to determine the type of layer surfaces and to possibly apply unique effects.

GTK Wayland only.

Available since: 1.2.0 ๐ŸŒธ

  • --quick-terminal-screen โ€” the screen where the quick terminal should show up.

Valid values are:

  • main โ€” The screen that the operating system recommends as the main screen. On macOS, this is the screen that is currently receiving keyboard input. This screen is defined by the operating system and not chosen by Ghostty.
  • mouse โ€” The screen that the mouse is currently hovered over.

main character screen energy ๐Ÿ–ฅ๏ธโœจ

  • macos-menu-bar โ€” the screen that has the macOS menu bar on it, like, the one set in display settings on macOS ๐Ÿ’…. Lowkey confusing tbh, because every screen on macOS technically has a menu bar, but this one is the screen holding the primary menu bar.

The default is main, because that's the screen the operating system itself recommends. Queen behavior ๐Ÿ‘‘.

On macOS, macos-menu-bar uses the screen that contains the menu bar. On Linux/Wayland, macos-menu-bar gets treated as exactly the same thing as main.

Note ๐Ÿซถ โ€” on Linux there's genuinely no universal concept of a "primary" monitor. Ghostty uses the compositor-reported primary output when it can get one, and falls back to the first monitor reported by GDK if no primary output can be resolved.

  • --quick-terminal-animation-duration โ€” how long, in seconds, the quick terminal's enter and exit animation takes ๐ŸŽฌ. Set it to 0 to kill the animation completely, no cap. This one can be changed at runtime, bestie.

Only implemented on macOS ๐Ÿ’ป.

  • --quick-terminal-autohide โ€” automatically hide the quick terminal when focus shifts to another window ๐Ÿ™ˆ. Set it to false if you want the quick terminal to stay open even when it loses focus.

Defaults to true on macOS and false on Linux/BSD. Why? Because global shortcuts on Linux need system configuration and are considerably less accessible than on macOS, so it's way preferable to keep the quick terminal open until the user has finished their task. This default may change in the future โ€” stay tuned โœจ.

  • --quick-terminal-space-behavior โ€” this one controls what the quick terminal does when you switch between macOS spaces ๐Ÿช. macOS spaces are the virtual desktops you can create manually, or that get auto-created when an app goes full-screen.

Valid values are:

  • move โ€” when you switch to another space, the quick terminal moves along to the current space too ๐Ÿšถโ€โ™€๏ธ.
  • remain โ€” the quick terminal stays only in the space where it was originally opened and does not follow you when you switch spaces ๐Ÿง˜โ€โ™€๏ธ.

The default value is move.

Only implemented on macOS. On Linux the behavior is always equivalent to move.

Available since: 1.1.0.

  • --quick-terminal-keyboard-interactivity โ€” decides under which circumstances the quick terminal should receive keyboard input โŒจ๏ธ. Peep the corresponding Wayland documentation for a way more detailed explanation of what each option does.
[!NOTE] โ€” the exact behavior of each option may differ significantly across compositors, so experiment on your system to find the one that suits your liking, fr fr ๐Ÿงช.

Valid values are:

  • none

The quick terminal will not receive any keyboard input at all ๐Ÿ™…โ€โ™€๏ธ.

  • on-demand (default)

The quick terminal only receives keyboard input when it's focused ๐Ÿ‘€.

  • exclusive

The quick terminal will always receive keyboard input, even when another window is currently focused ๐Ÿ’€.

Only has an effect on Linux Wayland. On macOS the behavior is always equivalent to on-demand.

Available since: 1.2.0.

  • --shell-integration โ€” whether to turn on shell integration auto-injection or not ๐Ÿšโœจ. Shell integration massively upgrades the terminal experience by unlocking a bunch of features:
    • Working directory reporting, so new tabs and splits inherit the previous terminal's working directory ๐Ÿ“‚.
    • Prompt marking, which is what makes the jump_to_prompt keybinding work ๐ŸŽฏ.
    • If you're sitting at a prompt, closing a terminal won't ask for confirmation ๐Ÿ™Œ.
    • Resizing the window with a complex prompt usually paints much better ๐ŸŽจ.

Allowable values are:

  • none โ€” do zero automatic injection. You can still manually configure your shell to enable the integration yourself ๐Ÿ› ๏ธ.
  • detect โ€” detect the shell based on the filename ๐Ÿ”.
  • bash, elvish, fish, nushell, zsh โ€” use this specific shell injection scheme ๐ŸŸ.

The default value is detect.

  • --shell-integration-features โ€” which shell integration features to enable ๐ŸŽ€. These require our shell integration to be loaded, either automatically via shell-integration or manually by you.

The format is a list of features separated by commas. Prefix a feature with no- and it's disabled. If you omit a feature, its default value is used โ€” so yes, you must explicitly disable the features you don't want, no shortcuts. You can also use true or false to turn all the features on or off at once.

Example: cursor, no-cursor, sudo, no-sudo, title, no-title

Available features:

  • cursor โ€” sets the cursor to a bar at the prompt ๐Ÿ–ฑ๏ธ.
  • sudo โ€” sets the sudo wrapper to preserve terminfo ๐Ÿ›ก๏ธ.
  • title โ€” sets the window title via shell integration ๐Ÿท๏ธ.
  • ssh-env โ€” enables SSH environment variable compatibility. Automatically converts TERM from xterm-ghostty to xterm-256color when connecting to remote hosts, and propagates COLORTERM, TERM_PROGRAM, and TERM_PROGRAM_VERSION. Whether or not those variables get accepted by the remote host(s) depends on whether they're allowed in their sshd_config ๐Ÿคทโ€โ™€๏ธ. (Available since: 1.2.0)
  • ssh-terminfo โ€” enables automatic terminfo installation on remote hosts. Attempts to install Ghostty's embedded terminfo entry using tic on local cache misses. Requires tic to be available on remote hosts. Successful installations are cached locally so it doesn't keep re-installing ๐Ÿ’พ. If you want, the +ssh-cache CLI action can manage the installation cache manually using various arguments. (Available since: 1.2.0)
  • path โ€” adds Ghostty's binary directory to PATH. This guarantees the ghostty command is available in the shell even if shell init scripts reset PATH ๐Ÿ›ค๏ธ. Super useful on macOS where PATH is often overridden by system scripts. The directory only gets added if it isn't already there.

The SSH features work independently and can be combined for the optimal experience: when both ssh-env and ssh-terminfo are enabled, Ghostty installs its terminfo on remote hosts and uses xterm-ghostty as TERM, falling back to xterm-256color with environment variables if the terminfo installation fails ๐ŸŒˆ.

  • --command-palette-entry โ€” custom entries for the command palette ๐Ÿ‘‘.

Each entry needs the title, the corresponding action, and an optional description. Every field gets prefixed with the field name, a colon (:), and then the value. The syntax for actions is identical to the one used for keybind actions. Whitespace between fields is ignored ๐Ÿซถ.

If you need to embed commas or any other special characters in the values, wrap the value in double quotes and it gets interpreted as a Zig string literal. That's also handy for including whitespace at the beginning or end of a value. Check the Zig documentation for more on string literals. Note that multiline string literals are not supported ๐Ÿ’€. And double quotes can not be used around field names.

command-palette-entry = title:Reset Font Style, action:csi:0m
command-palette-entry = title:Crash on Main Thread,description:Causes a crash on the main (UI) thread.,action:crash:main
command-palette-entry = title:Focus Split: Right,description:"Focus the split to the right, if it exists.",action:goto_split:right
command-palette-entry = title:"Ghostty",description:"Add a little Ghostty to your terminal.",action:"text:\xf0\x9f\x91\xbb"

There are also some extra special values you can specify for command-palette-entry:

  • command-palette-entry=clear will clear all command entries.
Warning โš ๏ธ โ€” this removes ALL entries up to this point, including the default entries. Available since: 1.4.0.

By default the command palette comes preloaded with most actions that might be useful in an interactive setting but don't have easily accessible or memorizable shortcuts. The default entries can be restored by setting this setting to an empty value:

command-palette-entry =

Available since: 1.2.0.

  • --osc-color-report-format โ€” sets the reporting format for OSC sequences that request color info ๐ŸŽจ. Ghostty currently supports OSC 10 (foreground), OSC 11 (background), and OSC 4 (256 color palette) queries, and by default the reported values are scaled-up RGB values where each component is 16 bits. That's how most terminals report these values. But some legacy apps may require 8-bit, unscaled components. Ghostty also supports turning reporting off entirely. The components are lowercase hex values, iykyk.

Allowable values are:

  • none โ€” OSC 4/10/11 queries receive no reply ๐Ÿค.
  • 8-bit โ€” color components are returned unscaled, e.g. rr/gg/bb.
  • 16-bit โ€” color components are returned scaled, e.g. rrrr/gggg/bbbb.

The default value is 16-bit.

  • --vt-kam-allowed โ€” if true, allows "KAM" mode (ANSI mode 2) to be used inside the terminal ๐Ÿง. KAM disables keyboard input at the request of the application. This is not a common feature and it is not recommended to enable it. It won't be documented any further, because if you know you need KAM, you know. And if you don't know whether you need KAM โ€” you don't need it ๐Ÿ’….
  • --vt-window-resize-allowed โ€” if true, lets the running program resize the window using the xterm CSI 8 ; rows ; columns t escape sequence ๐ŸชŸ. If a parameter is zero or omitted, the current size of that dimension is kept. Sizes smaller than 40 columns by 10 rows get raised to that size, so a program can't shrink the window down to hide its output ๐Ÿ™…โ€โ™€๏ธ.

Okay so real quick before we move on โ€” that whole resize thing has โœจconditionsโœจ, bestie. The request is completely ignored if the terminal is in a split, in a window with multiple tabs, or the quick terminal, or if the window manager is the one controlling the window size โ€” like when it's fullscreen, maximized, or tiled. And sizes larger than the screen get clamped to the screen. No negotiating.

This is disabled by default because it lets any program โ€” including one running on a remote machine โ€” change the size of your window. Which, respectfully, is terrifying ๐Ÿ’€.

Available since: 1.4.0

  • --vt-xt-checksum-report โ€” turns checksum reporting on or off (DECRQCRA, CSI Pi ; Pg ; Pt ; Pl ; Pb ; Pr * y). This escape sequence lets the running program ask for a checksum of an area of the screen โ€” terminal test suites use it to check what's actually on the screen.

It's disabled by default because a program can ask for the checksum of one cell at a time and therefore read back everything on the screen, including the output of other programs. Sneaky ๐Ÿ˜ญ.

While this is disabled, XTCHECKSUM (CSI Ps # y), which changes how the checksum is calculated, is ignored as well.

Available since: 1.4.0

  • --vt-xt-checksum-extension โ€” decides how the checksum reported for DECRQCRA (peep vt-xt-checksum-report) gets calculated. This is the calculation used after a reset, like xterm's checksumExtension resource. A running program can change it with XTCHECKSUM (CSI Ps # y) until the next reset. Default is the calculation of a real DEC terminal, no cap.

Valid values are:

  • negate โ€” report the negated sum, as DEC terminals do.
  • attributes โ€” add bold, underline, blink, inverse, invisible, and protected attributes to the value of each cell.
  • trim โ€” omit plain spaces other than the first cell of the area.
  • undrawn โ€” count cells that were never written to as spaces instead of skipping them.
  • full โ€” use the full codepoint of each cell instead of the DEC 8-bit value.

Prefix a value with no- to disable it. For example, esctest expects no-negate,no-attributes,no-trim,full when run with --xterm-checksum, which is xterm's checksumExtension: 23.

The bits of xterm's resource are described in its man page and its control sequence documentation, but where those disagree with xterm's implementation, Ghostty follows the implementation. The docs describe bit 3 as omitting cells that were never written to, but xterm skips those cells by default and counts them as spaces with the bit set โ€” which is undrawn here. It also lists a bit 5 that xterm doesn't implement. Documentation vs reality, classic ๐Ÿซ .

Available since: 1.4.0

  • --custom-shader โ€” custom shaders to run after the default shaders. This is a file path to a GLSL-syntax shader, for all platforms.
Warning: invalid shaders can cause Ghostty to become unusable, such as by causing the window to be completely black. If this happens, you can unset this configuration to disable the shader. Not me finding out the hard way ๐Ÿ™ˆ

Custom shader support is based on and compatible with the Shadertoy shaders. Shaders should specify a mainImage function, and the available uniforms largely match Shadertoy, with some caveats and Ghostty-specific extensions.

The uniform values available to shaders are as follows:

  • sampler2D iChannel0 โ€” input texture.

A texture containing the current terminal screen. If multiple custom shaders are specified, the output of previous shaders is written to this texture, to allow combining multiple effects.

  • vec3 iResolution โ€” output texture size, [width, height, 1] (in px).
  • float iTime โ€” time in seconds since first frame was rendered.
  • float iTimeDelta โ€” time in seconds since previous frame was rendered.
  • float iFrameRate โ€” average framerate. (NOT CURRENTLY SUPPORTED)
  • int iFrame โ€” number of frames that have been rendered so far.
  • float iChannelTime[4] โ€” current time for video or sound input. (N/A)
  • vec3 iChannelResolution[4] โ€” resolutions of the 4 input samplers.

Currently only iChannel0 exists, and iChannelResolution[0] is identical to iResolution.

  • vec4 iMouse โ€” mouse input info. (NOT CURRENTLY SUPPORTED)
  • vec4 iDate โ€” date/time info. (NOT CURRENTLY SUPPORTED)
  • float iSampleRate โ€” sample rate for audio. (N/A)

Ghostty-specific extensions:

  • vec4 iCurrentCursor โ€” info about the terminal cursor.
    • iCurrentCursor.xy is the -X, +Y corner of the current cursor.
    • iCurrentCursor.zw is the width and height of the current cursor.
  • vec4 iPreviousCursor โ€” info about the previous terminal cursor.
  • vec4 iCurrentCursorColor โ€” color of the terminal cursor.
  • vec4 iPreviousCursorColor โ€” color of the previous terminal cursor.
  • vec4 iCurrentCursorStyle โ€” style of the terminal cursor

Macros simplified use are defined for the various cursor styles:

  • CURSORSTYLE_BLOCK or 0
  • CURSORSTYLE_BLOCK_HOLLOW or 1
  • CURSORSTYLE_BAR or 2
  • CURSORSTYLE_UNDERLINE or 3
  • CURSORSTYLE_LOCK or 4
  • vec4 iPreviousCursorStyle โ€” style of the previous terminal cursor
  • vec4 iCursorVisible โ€” visibility of the terminal cursor.
  • float iTimeCursorChange โ€” timestamp of terminal cursor change.

When the terminal cursor changes position or color, this is set to the same time as the iTime uniform, allowing you to compute the time since the change by subtracting this from iTime.

  • float iTimeFocus โ€” timestamp when the surface last gained iFocus.

When the surface gains focus, this is set to the current value of iTime, similar to how iTimeCursorChange works. This allows you to compute the time since focus was gained or lost by calculating iTime - iTimeFocus. Use this to create animations that restart when the terminal regains focus.

  • int iFocus โ€” current focus state of the surface.

Set to 1.0 when the surface is focused, 0.0 when unfocused. This allows shaders to detect unfocused state and avoid animation artifacts from large time deltas caused by infrequent "deceptive frames" (e.g., modifier key presses, link hover events in unfocused split panes). Check iFocus > 0 to determine if the surface is currently focused.

  • vec3 iPalette[256] โ€” the 256-color terminal palette.

RGB values for all 256 colors in the terminal palette, normalized to [0.0, 1.0]. Index 0-15 are the ANSI colors, 16-231 are the 6x6x6 color cube, and 232-255 are the grayscale colors.

  • vec3 iBackgroundColor โ€” terminal background color (RGB).
  • vec3 iForegroundColor โ€” terminal foreground color (RGB).
  • vec3 iCursorColor โ€” terminal cursor color (RGB).
  • vec3 iCursorText โ€” terminal cursor text color (RGB).
  • vec3 iSelectionBackgroundColor โ€” selection background color (RGB).
  • vec3 iSelectionForegroundColor โ€” selection foreground color (RGB).

If the shader fails to compile, the shader will be ignored. Any errors related to shader compilation will not show up as configuration errors and only show up in the log, since shader compilation happens after configuration loading on the dedicated render thread. For interactive development, use shadertoy.com ๐Ÿ’–.

This can be repeated multiple times to load multiple shaders. The shaders will be run in the order they are specified.

This can be changed at runtime and will affect all open terminals.

  • --custom-shader-animation โ€” if true (default), the focused terminal surface will run an animation loop when custom shaders are used. This uses slightly more CPU (generally less than 10%) but allows the shader to animate. It only runs if there are custom shaders and the terminal is focused.

If this is set to false, the terminal and custom shader will only render when the terminal is updated. More efficient, but the shader won't animate. Trade-offs, bestie โœจ.

This can also be set to always, which will always run the animation loop regardless of whether the terminal is focused or not. The animation loop will still only run when custom shaders are used. Note that this will use more CPU per terminal surface and can become quite expensive depending on the shader and your terminal usage. Like, highkey expensive ๐Ÿ’€.

This can be changed at runtime and will affect all open terminals.

  • --bell-features โ€” bell features to enable if bell support is available in your runtime. Not all features are available on all runtimes. The format of this is a list of features to enable separated by commas. If you prefix a feature with no- then it is disabled. If you omit a feature, its default value is used.

Valid values are:

  • system

Instruct the system to notify the user using built-in system functions. This could result in an audiovisual effect, a notification, or something else entirely. Changing these effects require altering system settings: for instance under the "Sound > Alert Sound" setting in GNOME, or the "Accessibility > System Bell" settings in KDE Plasma.

On macOS, this plays the system alert sound.

  • audio

Play a custom sound. (Available since 1.3.0 on macOS)

  • attention (enabled by default)

Request the user's attention when Ghostty is unfocused, until it has received focus again. On macOS, this will bounce the app icon in the dock once. On Linux, the behavior depends on the desktop environment and/or the window manager/compositor:

  • On KDE, the background of the desktop icon in the task bar would be highlighted;
  • On GNOME, you may receive a notification that, when clicked, would bring the Ghostty window into focus;
  • On Sway, the window may be decorated with a distinctly colored border;
  • On other systems this may have no effect at all.

So yeah โ€” "it depends" energy, but at least it's documented ๐Ÿซถ

  • title (on by default โ€” yes bestie, it's already doing this) โ€” this one slaps a bell emoji (๐Ÿ””) in front of the title of the surface that pinged you, and it stays there until you re-focus the terminal or poke at it (like, y'know, typing on the keyboard). So you literally cannot miss who's yelling for you. ๐Ÿ’–
  • border โ€” draws a border around the alerted surface instead of/in addition to messing with the title. Same deal: it hangs around until the terminal is re-focused or interacted with (keyboard input counts). Visual pop-off, fr.

Available since: 1.2.0 on GTK, 1.2.1 on macOS

Example: audio, no-audio, system, no-system

Available since: 1.2.0

  • --bell-audio-path โ€” okay so if audio is one of your enabled bell features, this is the path to the audio file it plays. ๐ŸŽต If the path isn't absolute, it gets treated as relative to the directory of the config file it's referenced from โ€” or, if you're passing this as a CLI flag, relative to the current working directory. You can also prefix it with ~/ to point at the user's home directory, because obviously.

Available since: 1.2.0 on GTK, 1.3.0 on macOS.

  • --bell-audio-volume โ€” again, assuming audio is an enabled bell feature, this is the volume your little sound plays at, relative to the system volume. It's a floating point number from 0.0 (straight-up silence ๐Ÿคซ) to 1.0 (as loud as it gets ๐Ÿ”ฅ). Default is 0.5, so nice and polite.

Available since: 1.2.0 on GTK, 1.3.0 on macOS.

  • --app-notifications โ€” controls the in-app notifications Ghostty shows you. ๐ŸŽ€

On Linux (GTK), these show up as toasts โ€” little guys overlaid on top of your terminal window. They're for info that isn't critical but might still matter, iykyk.

The possible notifications are:

  • clipboard-copy (default: true) โ€” show a notification when text gets copied to the clipboard.
  • config-reload (default: true) โ€” show a notification when the config gets reloaded.

To enable a notification, just say its name. To disable one, prefix the name with no-. So like, to kill clipboard-copy you'd set this to no-clipboard-copy, and to bring it back you'd set it to clipboard-copy. Cute, right?

You can flip multiple notifications on or off at once by separating them with a comma.

A value of "false" disables all notifications, and a value of "true" enables all of them. Boom, mass toggle. ๐Ÿ’…

Heads up bestie: this configuration only applies to GTK.

Available since: 1.1.0

  • --macos-non-native-fullscreen โ€” if you set this to anything other than false, fullscreen mode on macOS stops using the native fullscreen and instead makes the window fullscreen with no animations, on a new space. It's faster than native fullscreen since, well, no animations. โšก
Important: tabs DO NOT WORK in this mode. Non-native fullscreen removes the titlebar, and macOS native tabs require the titlebar. So if you're a tabs girlie, do not use this mode. ๐Ÿ˜ญ

If you do fullscreen a window that has tabs, the currently focused tab becomes fullscreen while the rest chill in a separate window in the background. You can hop over to that window with your normal window-switching keybindings โ€” stuff like command+tilde. And when you exit fullscreen, the window goes right back to the tabbed state it was in before. Slay.

The allowable values are:

  • true โ€” use non-native macOS fullscreen, hide the menu bar
  • false โ€” use native macOS fullscreen
  • visible-menu โ€” use non-native macOS fullscreen, keep the menu bar visible
  • padded-notch โ€” use non-native macOS fullscreen, hide the menu bar, but make sure the window isn't obscured by the notch on devices that have one. The area around the notch currently stays transparent, but in the future it might get filled with the window background color. ๐Ÿ‘€

Changing this option at runtime works, but it only applies the next time the window goes fullscreen. If a window is already fullscreen, it keeps the previous setting until you exit fullscreen. Annoying but fair.

  • --macos-window-buttons โ€” whether the window buttons in the macOS titlebar are visible. The window buttons are the colored ones in the upper left of most macOS apps โ€” the traffic lights ๐Ÿšฆ โ€” that let you close, miniaturize, and zoom the window.
Ngl this setting does nothing when window-decoration = none or macos-titlebar-style = hidden, since the window buttons are always hidden in those modes anyway.

Valid values are:

  • visible โ€” show the window buttons.
  • hidden โ€” hide the window buttons.

The default value is visible.

Changing this at runtime only applies to new windows.

Available since: 1.2.0

  • --macos-titlebar-style โ€” the style of the macOS titlebar. Available values are: "native", "transparent", "tabs", and "hidden". Let's break them down bestie:

The "native" style uses the native macOS titlebar with zero customization. The titlebar matches your window theme (see window-theme).

The "transparent" style is the same as "native" except the titlebar is transparent and lets your window background color come through. More seamless window appearance, but it looks a little less typical for a macOS app and might not play nice with every theme.

The "transparent" style also updates in real-time when the window background color changes dynamically โ€” e.g. via OSC 11. โœจ And to make that more aesthetically pleasing, it only happens if the terminal is a window, tab, or split that borders the top of the window. That way you don't get a disjointed look where the titlebar color changes but all the topmost terminals don't match. We love a thoughtful detail.

The "tabs" style is a completely custom titlebar that integrates the tab bar into the titlebar itself. This titlebar always matches the background color of the terminal. Limitations exist though: on macOS 13 and below, saved window state will not restore tabs correctly. macOS 14 doesn't have this issue, and any other macOS version hasn't been tested. ๐Ÿ™ˆ

The "hidden" style hides the titlebar. Unlike window-decoration = none, though, it does not remove the frame from the window or give it squared corners. Changing to or from this option at runtime may affect existing windows in buggy ways. ๐Ÿ’€

When it's "hidden", the top titlebar area can no longer be used for dragging the window. To drag it, you can use option+click on the resizable areas of the frame. That's a standard macOS behavior, not something Ghostty enables.

The default value is "transparent". It's an opinionated choice, but it's the one the author thinks is the most aesthetically pleasing and works in most cases. ๐Ÿซถ

Changing this option at runtime only applies to new windows.

  • --macos-titlebar-proxy-icon โ€” whether the proxy icon in the macOS titlebar is visible. The proxy icon is that little icon representing the folder of the current working directory โ€” you can see it super clearly in the macOS built-in Terminal.app titlebar. ๐ŸŽ€
Reminder: the proxy icon is only visible with the native macOS titlebar style.

Valid values are:

  • visible โ€” show the proxy icon.
  • hidden โ€” hide the proxy icon.

The default value is visible.

This one can be changed at runtime and it affects all currently open windows โ€” but only after their working directory changes again. So to make it actually kick in after you change the setting, you usually have to cd to a different directory, open a different file in your editor, etc. Patience, bestie.

  • --macos-dock-drop-behavior โ€” controls what happens window-wise when you drop a file or folder onto the Ghostty icon in the macOS dock. ๐Ÿฆ‹

Valid values are:

  • new-tab โ€” create a new tab in the current window, or open a new window if none exist.
  • new-window โ€” create a new window unconditionally.

The default value is new-tab.

This setting is only supported on macOS and does nothing on other platforms.
  • --macos-option-as-alt โ€” okay, so macOS doesn't have a distinct "alt" key; it has the "option" key, which behaves a little differently. On macOS by default, option plus a character sometimes produces a Unicode character. Example: on US standard layouts, option-b gives you "โˆซ". And that's maybe not what you want if you're trying to use "option" as an "alt" key for keybindings in terminal programs or shells. ๐Ÿ˜ค

This configuration lets you change the behavior so option is treated as alt.

The default behavior (unset) depends on your active keyboard layout. If your layout is one of the ones listed below, the default value is "true". Otherwise the default is "false". The keyboard layouts whose default is "true" are:

  • U.S. Standard
  • U.S. International
Note that if an Option-sequence doesn't produce a printable character, it'll be treated as Alt regardless of this setting โ€” e.g. alt+ctrl+a.

Explicit values you can set:

If true, the Option key is treated as Alt. This makes terminal sequences that expect Alt work properly, but it will break Unicode input sequences on macOS if you use them via the Alt key. ๐Ÿซ 

You can set it to false to restore the macOS Alt key unicode sequences, but that will break terminal sequences expecting Alt. Pick your fighter.

The values left or right enable this for the left or right Option key, respectively.

  • --macos-window-shadow โ€” whether to enable the macOS window shadow. The default value is true. With some window managers and window transparency settings, you might find false more visually appealing. Your call, icon. ๐Ÿ’…
  • --macos-hidden โ€” if true, the macOS icon in the dock and app switcher will be hidden. This is mainly intended for people primarily using the quick-terminal mode. ๐Ÿ™ˆ
Heads up: setting this to true means keyboard layout changes will no longer be automatic.

...whether the macOS app gets left out of the dock and the app switcher โ€” that whole โ€œhiddenโ€ vibe. It's mostly there for the girlies living in quick-terminal mode, but honestly it's a general config that works for literally any use case.

Available values:

  • never โ€” the macOS app is never hidden. Ever. She's out and proud.
  • always โ€” the macOS app is always hidden. Sneaky era. ๐Ÿซฅ
Note: when the macOS app is hidden, keyboard layout changes stop being automatic. That's not Ghostty being weird, it's a macOS limitation. Not us, not our fault. ๐Ÿ˜ญ

Available since: 1.2.0


  • --macos-auto-secure-input โ€” if true, Ghostty on macOS will automatically turn on the โ€œSecure Inputโ€ feature the second it detects a password prompt is being displayed. ๐ŸŽ€

โ€œSecure Inputโ€ is a macOS security feature that stops applications from reading keyboard events. You can always enable it manually via the Ghostty > Secure Keyboard Entry menu item, if you're feeling hands-on.

Heads up though: the automatic password prompt detection is based on heuristics, so it may not always work as expected. Specifically, it does not work over SSH connections โ€” but there may be other cases where it also doesn't work. Lowkey just vibes-based detection. ๐Ÿ™ˆ

One reason you might want to disable this: if you find it's interfering with legitimate accessibility software (or software that uses the accessibility APIs), since secure input prevents any application from reading keyboard events.

  • --macos-secure-input-indication โ€” if true, Ghostty shows a graphical indication when secure input is enabled. Genuinely recommended, because how else are you supposed to know? ๐Ÿ‘€

Normally, secure input is only active while a password prompt is displayed, or when it's manually (and typically temporarily) enabled. But if you always have secure input enabled, that indication can get distracting, and you may want to disable it.

  • --macos-applescript โ€” if true, Ghostty exposes and handles the built-in AppleScript dictionary on macOS. ๐ŸŽ

If false, all AppleScript interactions are disabled. That includes AppleScript commands and AppleScript object lookup for windows, tabs, and terminals. All of it. Gone.

The default is true.

  • --macos-icon โ€” customize the macOS app icon. Main character customization, fr. ๐Ÿ’…

This only affects the icon that appears in the dock, application switcher, etc. It does not affect the icon in Finder, because that one is controlled by a hardcoded value in the signed application bundle and can't be changed at runtime. For more details on what exactly is affected, see the NSApplication.icon Apple documentation โ€” that is the API being used to set the icon.

Valid values:

  • official โ€” use the official Ghostty icon.
  • blueprint, chalkboard, microchip, glass, holographic, paper, retro, xray โ€” official variants of the Ghostty icon, hand-created by artists (no AI ๐Ÿค–๐Ÿšซ).
  • custom โ€” use a completely custom icon. The location must be specified using the additional macos-custom-icon configuration.
  • custom-style โ€” use the official Ghostty icon but with custom styles applied to various layers. The custom styles must be specified using the additional macos-icon-prefixed configurations. The macos-icon-ghost-color and macos-icon-screen-color configurations are required for this style.
WARNING: the custom-style option is experimental. We may change the format of the custom styles in the future. We're still finalizing the exact layers and customization options that will be available. Consider yourself warned, bestie. ๐Ÿ’€

Other caveats:

  • The icon in the update dialog will always be the official icon. This is because the update dialog is managed through a separate framework and cannot be customized without significant effort. Sorry, she's built different and we can't touch her.
  • --macos-custom-icon โ€” the absolute path to the custom icon file. Supported formats include PNG, JPEG, and ICNS. ๐Ÿ–ผ๏ธ

Defaults to ~/.config/ghostty/Ghostty.icns

  • --macos-icon-frame โ€” the material to use for the frame of the macOS app icon. It's giving hardware but make it couture. โœจ

Valid values:

  • aluminum โ€” a brushed aluminum frame. This is the default.
  • beige โ€” a classic 90's computer beige frame. Retro iykyk.
  • plastic โ€” a glossy, dark plastic frame.
  • chrome โ€” a shiny chrome frame.
Note: this configuration is required when macos-icon is set to custom-style.
  • --macos-icon-ghost-color โ€” the color of the ghost in the macOS app icon. ๐Ÿ‘ป๐Ÿ’–
Note: this configuration is required when macos-icon is set to custom-style.

Specified as either hex (#RRGGBB or RRGGBB) or a named X11 color.

  • --macos-icon-screen-color โ€” the color of the screen in the macOS app icon. ๐ŸŒˆ

The screen is a linear gradient, so you can specify multiple colors that make up the gradient. Up to 64 comma-separated colors may be specified as either hex (#RRGGBB or RRGGBB) or as named X11 colors. The first color is the bottom of the gradient and the last color is the top of the gradient. Gradient math, slay.

Note: this configuration is required when macos-icon is set to custom-style.
  • --macos-shortcuts โ€” whether macOS Shortcuts are allowed to control Ghostty. ๐ŸŽ›๏ธ

Ghostty exposes a number of actions that allow Shortcuts to control and interact with Ghostty. This includes creating new terminals, sending text to terminals, running commands, invoking any keybind action, etc.

This is a powerful feature, but it can be a security risk if a malicious shortcut is able to be installed and executed. So this configuration lets you disable the whole thing.

Valid values are:

  • ask โ€” ask the user for permission. Ghostty will remember this choice and never ask again. This is similar to other macOS permissions such as microphone access, camera access, etc.
  • allow โ€” allow Shortcuts to control Ghostty without asking.
  • deny โ€” deny Shortcuts from controlling Ghostty.

Available since: 1.2.0

  • --linux-cgroup โ€” put every surface (tab, split, window) into a transient systemd scope. ๐Ÿง

This allows per-surface resource management. For example, if a shell program is using too much memory, only that shell will be killed by the oom monitor instead of the entire Ghostty process. Similarly, if a shell program is using too much CPU, only that surface will be CPU-throttled. Containment, periodt.

This will cause startup times to be slower (a hundred milliseconds or so), so the default value is โ€œsingle-instance.โ€ In single-instance mode, only one instance of Ghostty is running (see gtk-single-instance), so the startup time is a one-time cost. Additionally, single instance Ghostty is much more likely to have many windows, tabs, etc., so cgroup isolation is a big benefit.

This feature requires systemd. If systemd is unavailable, cgroup initialization will fail. By default, this will not prevent Ghostty from working (see linux-cgroup-hard-fail).

Changing this value and reloading the config will not affect existing surfaces.

Valid values are:

  • never โ€” never use cgroups.
  • always โ€” always use cgroups.
  • single-instance โ€” enable cgroups only for Ghostty instances launched as single-instance applications (see gtk-single-instance).
  • --linux-cgroup-memory-limit โ€” memory limit for any individual terminal process (tab, split, window, etc.) in bytes. If this is unset, then no memory limit will be set. ๐Ÿง 

Note that this sets the MemoryHigh setting on the transient systemd scope, which is a soft limit. You should configure something like systemd-oom to handle killing processes that have too much memory pressure.

Changing this value and reloading the config will not affect existing surfaces.

See the systemd.resource-control manual page for more information: https://www.freedesktop.org/software/systemd/man/latest/systemd.resource-control.html

  • --linux-cgroup-processes-limit โ€” number of processes limit for any individual terminal process (tab, split, window, etc.). If this is unset, then no limit will be set. ๐Ÿงฎ

Note that this sets the TasksMax setting on the transient systemd scope, which is a hard limit.

Changing this value and reloading the config will not affect existing surfaces.

See the systemd.resource-control manual page for more information: https://www.freedesktop.org/software/systemd/man/latest/systemd.resource-control.html

  • --linux-cgroup-hard-fail โ€” if this is false, then creating a transient systemd scope (for linux-cgroup) will be allowed to fail, and the failure is ignored. This is useful if you view cgroup isolation as a โ€œnice to haveโ€ and not a critical resource management feature, because surface creation will not fail if systemd APIs fail. ๐Ÿซถ

If this is true, then any transient systemd scope creation failure will cause surface creation to fail. No scope, no surface. Brutal but honest.

Changing this value and reloading the config will not affect existing surfaces.

  • --gtk-opengl-debug โ€” enable or disable GTK's OpenGL debugging logs. The default is true for debug builds, false for all others. ๐Ÿ”

Available since: 1.1.0

  • --gtk-single-instance โ€” if true, the Ghostty GTK application will run in single-instance mode: each new ghostty process launched will result in a new window if there is already a running process. ๐ŸชŸ

If false, each new ghostty process will launch a separate application.

If detect, Ghostty will assume true (single instance) unless one of the following scenarios is found:

  1. TERM_PROGRAM environment variable is a non-empty value. In this case, we assume Ghostty is being launched from a graphical terminal session and you want a dedicated instance.
  2. Any CLI arguments exist. In this case, we assume you are passing custom Ghostty configuration. Single instance mode inherits the configuration from when it was launched, so we must disable single instance to load the new configuration.

If either of these scenarios is producing a false positive, you can set this configuration explicitly to the behavior you want.

The pre-1.2 option desktop has been deprecated. Please replace this with detect.

The default value is detect.

Note that debug builds of Ghostty have a separate single-instance ID so you can test single instance without conflicting with release builds.

  • --gtk-titlebar โ€” turn this on and you get the full GTK titlebar instead of your window manager's cute little simple titlebar ๐Ÿ’…. Heads up though: how this actually looks varies with your window manager, so it's giving "results may vary" energy.

This option does nothing when window-decoration is none, or when you're running under macOS. Sorry bestie, Macs don't get this one ๐Ÿ“.

  • --gtk-tabs-location โ€” decides which side of the screen the GTK tab bar sticks to. The supported values are top, bottom, and hidden. Default is top โœจ.

When hidden is set, a tab button showing the number of tabs pops up in the title bar โ€” it can open a tab overview for displaying tabs. Or, if your window has no title bar, you can use the toggle_tab_overview action in a keybind instead. Keybinds to switch tabs also work, iykyk ๐Ÿฆ‹.

  • --gtk-tabs-inverted โ€” if true, each tab's close button shows up at the start of the tab (the left side, in left-to-right languages) and the tab's icon goes at the end ๐ŸŽ€. This applies to both the tab bar and the tab overview. GTK only.

Available since: 1.4.0

  • --gtk-titlebar-hide-when-maximized โ€” if this is true, the titlebar gets hidden when the window is maximized, and shown again when it's unmaximized ๐Ÿซถ. GTK only, no cap.

Available since: 1.1.0

  • --gtk-toolbar-style โ€” determines the appearance of the top and bottom bars tab bar โญ.

Valid values are:

  • flat โ€” Top and bottom bars are flat with the terminal window.
  • raised โ€” Top and bottom bars cast a shadow on the terminal area.
  • raised-border โ€” Similar to raised but the shadow is replaced with a more subtle border.
  • --gtk-titlebar-style โ€” the style of the GTK titlebar ๐Ÿ’–. Available values are native and tabs.

The native titlebar style is a traditional titlebar with a title, a few buttons and window controls. A separate tab bar will show up below the titlebar if you have multiple tabs open in the window.

The tabs titlebar merges the tab bar and the traditional titlebar together. This frees up vertical space on your screen if you use multiple tabs โ€” main character energy for your screen real estate honestly ๐Ÿ‘‘. One limitation of the tabs titlebar: you can't drag the titlebar by the titles any longer (because they're tab titles now, bestie ๐Ÿ˜ญ). Other areas of the tabs title bar can still be used to drag the window around.

The default style is native.

  • --gtk-wide-tabs โ€” if true (default), then the Ghostty GTK tabs will be "wide." Wide tabs are the new typical Gnome style where tabs fill their available space ๐ŸŒธ. Set this to false and tabs will only take up the space they need, which is the old style.
  • --gtk-horizontal-tab-scroll โ€” if true (default), then two-finger horizontal scrolling on a touchpad will switch between tabs ๐Ÿงš. Scrolling left goes to the next tab, scrolling right goes to the previous tab. Set this to false to disable this behavior.

Available since 1.4.0.

  • --gtk-custom-css โ€” custom CSS files to be loaded, literally the stylist era of your terminal ๐Ÿ’….

GTK CSS documentation lives at these links:

Launch Ghostty with env GTK_DEBUG=interactive ghostty to tweak Ghostty's CSS in real time using the GTK Inspector ๐Ÿ”ฅ. Errors in your CSS files would also be reported in the terminal you started Ghostty from. See https://developer.gnome.org/documentation/tools/inspector.html for more information about the GTK Inspector.

This configuration can be repeated multiple times to load multiple files. Prepend a ? character to the file path to suppress errors if the file does not exist ๐Ÿ™ˆ. If you want to include a file that begins with a literal ? character, surround the file path in double quotes ("). The file size limit for a single stylesheet is 5MiB.

Available since: 1.1.0

  • --desktop-notifications โ€” if true (default), applications running in the terminal can show desktop notifications using certain escape sequences such as OSC 9 or OSC 777 ๐Ÿฆ‹โœจ.
  • --progress-style โ€” if true (default), applications running in the terminal can show graphical progress bars using the ConEmu OSC 9;4 escape sequence ๐Ÿ“Š. If false, progress bar sequences are silently ignored โ€” ghosted, no drama ๐Ÿ’€.
  • --bold-color โ€” modifies the color used for bold text in the terminal, the glow-up of fonts basically โœจ.

This can be set to a specific color, using the same format as background or foreground (e.g. #RRGGBB but other formats are also supported; see the aforementioned documentation). If a specific color is set, this color will always be used for the default bold text color. It will set the rest of the bold colors to bright.

This can also be set to bright, which uses the bright color palette for bold text ๐Ÿ”ฅ. For example, if the text is red, then the bold will use the bright red color. The terminal palette is set with palette but can also be overridden by the terminal application itself using escape sequences such as OSC 4. (Since Ghostty 1.2.0, the previous configuration bold-is-bright is deprecated and replaced by this usage.)

Available since Ghostty 1.2.0.

  • --faint-opacity โ€” the opacity level (opposite of transparency) of the faint text ๐Ÿซง. A value of 1 is fully opaque and a value of 0 is fully transparent. A value less than 0 or greater than 1 will be clamped to the nearest valid value.

Available since Ghostty 1.2.0.

  • --term โ€” this will be used to set the TERM environment variable. HACK ALERT โš ๏ธ: we set this with an xterm prefix because vim uses that to enable key protocols (specifically this will enable modifyOtherKeys), among other features. An option exists in vim to modify this: :set keyprotocol=ghostty:kitty, however a bug in the implementation prevents it from working properly. https://github.com/vim/vim/pull/13211 fixes this. Trap acknowledged, patch pending ๐Ÿ˜ญ.
  • --enquiry-response โ€” string to send when we receive ENQ (0x05) from the command that we are running ๐Ÿ“จ. Defaults to an empty string if not set.
  • --async-backend โ€” configures the low-level API to use for async IO, eventing, etc. โš™๏ธ

Most users should leave this set to auto ๐Ÿ™. This will automatically detect scenarios where APIs may not be available (for example io_uring on certain hardened kernels) and fall back to a different API. However, if you want to force a specific backend for any reason, you can set this here.

Based on various benchmarks, we haven't found a statistically significant difference between the backends with regards to memory, CPU, or latency ๐Ÿ“ˆ. The choice of backend is more about compatibility and features.

Available options:

  • auto โ€” Automatically choose the best backend for the platform based on available options.
  • epoll โ€” Use the epoll API
  • io_uring โ€” Use the io_uring API

If the selected backend is not available on the platform, Ghostty will fall back to an automatically chosen backend that is available.

Changing this value requires a full application restart to take effect. No hot-swapping bestie, sorry ๐Ÿ’€.

This is only supported on Linux, since this is the only platform where we have multiple options. On macOS, we always use kqueue ๐Ÿ“.

Available since: 1.2.0

  • --auto-update โ€” control the auto-update functionality of Ghostty ๐Ÿ”„. This is only supported on macOS currently, since Linux builds are distributed via package managers that are not centrally controlled by Ghostty.

Checking or downloading an update does not send any information to the project beyond standard network information mandated by the underlying protocols. To put it another way: Ghostty doesn't explicitly add any tracking to the update process ๐Ÿ‘‘. The update process works by downloading information about the latest version and comparing it client-side to the current version.

Valid values are:

  • off โ€” Disable auto-updates.
  • check โ€” Check for updates and notify the user if an update is available, but do not automatically download or install the update.
  • download โ€” Check for updates, automatically download the update, notify the user, but do not automatically install the update.

If unset, we defer to Sparkle's default behavior, which respects the preference stored in the standard user defaults (defaults(1)).

Changing this value at runtime works after a small delay ๐Ÿซถ.

  • --auto-update-channel โ€” the release channel to use for auto-updates ๐ŸŽ€.

The default value of this matches the release channel of the currently running Ghostty version. If you download a pre-release version of Ghostty then this will be set to tip and you will receive pre-release updates. If you download a stable version of Ghostty then this will be set to stable and you will receive stable updates.

Valid values are:

  • stable โ€” Stable, tagged releases such as "1.0.0".
  • tip โ€” Pre-release versions generated from each commit to the main branch. This is the version that was in use during private beta testing by thousands of people. It is generally stable but will likely have more bugs than the stable channel ๐Ÿ›.
Changing this configuration requires a full restart of Ghostty to take effect.

This only works on macOS since only macOS has an auto-update feature ๐Ÿ“.


๐ŸŽ€ FILES ๐ŸŽ€

okay so here's where Ghostty goes looking for your stuff โ€” write these down bestie, fr fr ๐Ÿ’–

  • $XDG_CONFIG_HOME/ghostty/config.ghostty โ€” this is the location of the default configuration file. that's it, that's the tweet โœจ
  • $HOME/Library/Application Support/com.mitchellh.ghostty/config.ghostty โ€” on macOS, this is the location of the default configuration file. and listen ๐Ÿ‘€ this location takes precedence over the XDG environment locations, so on Mac it wins, no cap ๐Ÿ‘‘
  • $LOCALAPPDATA/ghostty/config.ghostty โ€” on Windows, if $XDG_CONFIG_HOME is not set, then $LOCALAPPDATA will be searched for configuration files ๐ŸชŸ

๐ŸŒˆ ENVIRONMENT ๐ŸŒˆ

the env vars, the whole env vars, and nothing but the env vars โ€” let's go ๐Ÿ’…

  • TERM โ€” defaults to xterm-ghostty. you can configure it with the term configuration option โœจ
  • GHOSTTY_RESOURCES_DIR โ€” where the Ghostty resources can be found. that's where the good stuff lives ๐ŸŽ€
  • XDG_CONFIG_HOME โ€” the default location for configuration files ๐Ÿฆ‹
  • $HOME/Library/Application Support/com.mitchellh.ghostty โ€” MACOS ONLY default location for configuration files. this location takes precedence over the XDG environment locations ๐ŸŽ
  • LOCALAPPDATA โ€” WINDOWS ONLY: alternate location to search for configuration files ๐ŸชŸ

๐Ÿ’œ GHOSTTY_LOG ๐Ÿ’œ

okay so the GHOSTTY_LOG environment variable is your log-routing bestie โ€” you use it to control which destinations receive logs. Ghostty currently defines two destinations, and they are:

  • stderr โ€” logging to stderr ๐Ÿ“œ
  • macos โ€” logging to macOS's unified log (and ngl, this one has no effect on non-macOS platforms, so don't come for it on Linux ๐Ÿ™ˆ)

you combine values with a comma to enable multiple destinations โ€” yes, commas, we love a list ๐ŸŒธ

you prefix a destination with no- to disable it. and the fun part? enabling and disabling destinations can be done at the same time, so go off ๐Ÿ’…

also: setting GHOSTTY_LOG to true will enable all destinations. setting GHOSTTY_LOG to false will disable all destinations. simple as that, periodt โญ


๐Ÿ’€ BUGS ๐Ÿ’€

found a bug? see GitHub issues, bestie: https://github.com/ghostty-org/ghostty/issues โ€” take it there ๐Ÿซถ


๐Ÿ‘‘ AUTHOR ๐Ÿ‘‘

Mitchell Hashimoto m@mitchellh.com and Ghostty contributors.

contributors live here: https://github.com/ghostty-org/ghostty/graphs/contributors โ€” iconic behavior honestly ๐Ÿ’–


๐Ÿฆ‹ SEE ALSO ๐Ÿฆ‹

ghostty(5) โ€” go read that one too, iykyk โœจ


and that's the whole page, bestie!! you made it to the end, main character energy only ๐ŸŒŸ

thanks for reading the Ghostty manual page โ€” this is Version 1.4.0-arch1, living in section GHOSTTY(1), and it was made with so much love (and a truly unreasonable number of emoji) by me, for you ๐ŸŽ€๐Ÿ’œ๐ŸŒธ slay, go open a terminal, and don't forget to hydrate ๐Ÿ“

๐Ÿ“ฆ where this page comes from