# How to Configure Custom Key Bindings in Ghostty: A Complete Guide

> Learn how to configure custom key bindings in Ghostty by editing your config file. This guide explains the keybind syntax for personalized shortcuts and commands.

- Repository: [Ghostty/ghostty](https://github.com/ghostty-org/ghostty)
- Tags: how-to-guide
- Published: 2026-05-01

---

**You configure custom key bindings in Ghostty by editing the `keybind` field in your configuration file (default `~/.config/ghostty/config`) using the syntax `keybind = <prefixes><key-spec>=<action>`.**

Ghostty’s input system is defined in the `ghostty-org/ghostty` repository and centers on the `Config` struct in **src/config/Config.zig**. When the terminal launches, it parses your configuration file and builds an internal key map that translates incoming key events into executable actions. This guide explains the exact syntax, prefixes, and internal flow used by the configuration parser to help you customize your workflow.

## Understanding the Key Binding Syntax

Every binding in Ghostty consists of three distinct components parsed from the `keybind` field (defined at [line 1860](https://github.com/ghostty-org/ghostty/blob/main/src/config/Config.zig#L1860) of **src/config/Config.zig**).

### 1. Optional Prefixes

Prefixes modify how the binding behaves and can be stacked using colons. According to the source comments at [lines 49-51](https://github.com/ghostty-org/ghostty/blob/main/src/config/Config.zig#L49-51), the available prefixes are:

- **global:** – Activates the binding even when Ghostty is not focused (requires OS-level support on macOS and Wayland).
- **unconsumed:** – Executes the action but allows the raw key event to pass through to the running terminal program.
- **performable:** – Only consumes the input if the associated action can actually be executed in the current context.

Example of stacked prefixes:

```ini
keybind = global:unconsumed:ctrl+a=reload_config

```

### 2. Key Specification

This defines the physical input using modifier keys and key names. Valid modifiers are `ctrl`, `alt`, `shift`, `super` (or `cmd` on macOS). Keys are referenced by their textual name, such as `a`, `backquote`, or `escape`.

You can also define **key sequences** by separating keystrokes with `>`. This is documented at [lines 87-90](https://github.com/ghostty-org/ghostty/blob/main/src/config/Config.zig#L87-90):

```ini

# Trigger action only after pressing Ctrl+A followed by N

keybind = ctrl+a>n=new_window

```

### 3. Action

The final component is the action name, which must match an entry in the `Action` enum defined in **src/input/Binding.zig** ([lines 45-71](https://github.com/ghostty-org/ghostty/blob/main/src/input/Binding.zig#L45-71)). Common actions include `new_window`, `new_split`, `copy_to_clipboard`, `reload_config`, and `quit`.

## Creating Chained Actions

You can trigger multiple actions from a single key press using the `chain=` keyword. The first line establishes the base binding; subsequent lines prefixed with `chain=` add additional steps. All chained actions inherit the prefixes of the original binding.

```ini

# Open a new split to the right, then immediately focus the left pane

keybind = ctrl+shift+s=new_split:right
keybind = chain=goto_split:left

```

## Using Key Tables for Modal Bindings

Ghostty supports **named key tables** that function like modal modes in Vim. This allows you to create dedicated key maps for specific contexts, such as copy mode or command palettes.

Define a table by prefixing the binding with `<table>/`. For example, creating a `vim` table is shown in the source at [lines 25-30](https://github.com/ghostty-org/ghostty/blob/main/src/config/Config.zig#L25-30):

```ini
keybind = vim/esc=deactivate_key_table
keybind = vim/h=move_left
keybind = vim/j=move_down
keybind = vim/k=move_up
keybind = vim/l=move_right

```

You control table activation using actions defined in **src/input/Binding.zig** ([lines 78-99](https://github.com/ghostty-org/ghostty/blob/main/src/input/Binding.zig#L78-99)):

- **activate_key_table** – Switches to the named table indefinitely.
- **activate_key_table_once** – Switches to the table for one action only, then returns to the default table.
- **deactivate_key_table** – Returns to the default key table.

## How Ghostty Processes Key Bindings Internally

The binding system follows a three-phase pipeline:

1. **Configuration Loading** – The `Config.load` function reads your configuration file and populates the `keybind: Keybinds = .{}` field. This occurs at startup and during config reloads.
2. **Key Map Construction** – `Keybinds.init` builds an internal hash table that maps encoded key events (generated by **src/input/key_encode.zig**) to their corresponding `Action` values.
3. **Event Dispatch** – When a key event arrives in **src/termio/Termio.zig**, the system calls `Keybinds.lookup`. If a match exists, the associated action is dispatched immediately; otherwise, the raw key event is passed through to the terminal’s PTY.

## Inspecting Your Active Configuration

To verify which bindings are currently loaded without launching the full terminal, use the built-in CLI command implemented in **src/cli/list_keybinds.zig**:

```bash
ghostty +list-keybinds

```

This outputs the complete mapping table, including any custom tables you have defined.

## Summary

- Ghostty stores bindings in the **`keybind`** field of **src/config/Config.zig**, parsed at startup via `Config.load`.
- Use **prefixes** (`global:`, `unconsumed:`, `performable:`) to modify binding scope and consumption behavior.
- Define **sequences** with `>` and **chained actions** with `chain=` to build complex workflows.
- Create **modal key tables** by prefixing bindings with a table name (e.g., `vim/ctrl+h=move_left`) and switch tables using `activate_key_table`.
- Inspect the active configuration by running **`ghostty +list-keybinds`**.

## Frequently Asked Questions

### How do I make a key binding work even when Ghostty is not focused?

Add the `global:` prefix to your binding. For example, `keybind = global:cmd+backquote=toggle_quick_terminal` allows you to toggle the quick terminal from any application on supported platforms (macOS and Wayland). This requires OS-specific APIs and may not function on all systems.

### What is the difference between `unconsumed:` and standard key bindings?

A standard binding consumes the key event, meaning the running terminal application never receives it. The `unconsumed:` prefix executes your configured action but still passes the raw key event to the shell or program running in the terminal. This is useful for reloading configuration while keeping the keystroke available to the underlying process.

### Can I use key sequences like Emacs or Vim chorded commands?

Yes. Ghostty supports sequences using the `>` character. For example, `keybind = ctrl+a>n=new_window` requires pressing `Ctrl+A`, releasing it, then pressing `N` to trigger the action. Sequences can be combined with any prefix or action type.

### Where can I find the complete list of available actions for key bindings?

The authoritative list is the `Action` enum in **src/input/Binding.zig** ([lines 45-71](https://github.com/ghostty-org/ghostty/blob/main/src/input/Binding.zig#L45-71)). You can also view your currently active bindings and their associated actions by running `ghostty +list-keybinds` from your terminal.