← Back to Blog

Claude Code Keyboard Shortcuts & Keybindings (2026)

Claude Code's default keyboard shortcuts, how to customize keybindings.json, chord bindings, vim mode, and rebinding the submit key.


Claude Code ships with a full keyboard-driven interface, but almost nobody uses more than four or five shortcuts out of the box. Part of that is discoverability — there's no menu bar to hover over. Part of it is that the defaults conflict with muscle memory from tmux, vim, or whatever terminal multiplexer you already live in.

As of v2.1.18, every shortcut is customizable. Run /keybindings and Claude Code opens ~/.claude/keybindings.json, a config file that controls every keystroke in the app — chat input, permission dialogs, the diff viewer, background task management, all of it. Here's what's bound by default, how to remap it, and the gotchas that trip people up.

The Shortcuts You Actually Need First

Before touching the config file, these are the defaults worth memorizing:

Shift+Tab       Cycle permission modes (default → auto-accept → plan mode)
Ctrl+R          Search command history
Ctrl+O          Toggle verbose transcript
Ctrl+T          Toggle the to-do checklist
Ctrl+L          Redraw screen (press twice fast to run /clear)
Ctrl+J          Insert a newline without submitting
Ctrl+_          Undo last action
Ctrl+B          Background the current task
Ctrl+C          Interrupt / cancel (hardcoded, can't rebind)
Ctrl+D          Exit Claude Code (hardcoded, can't rebind)

The one that changes how you work day to day is Shift+Tab. It cycles between permission modes mid-conversation — useful when you start in default mode to review a risky change, then flip to auto-accept once you trust what the agent is doing. Our permission modes guide covers what each mode actually restricts.

The Config File Structure

The keybindings file is a single JSON object with a bindings array. Each entry in that array targets a specific context — the part of the UI where the binding applies — and maps keystrokes to actions:

{
  "$schema": "https://www.schemastore.org/claude-code-keybindings.json",
  "$docs": "https://code.claude.com/docs/en/keybindings",
  "bindings": [
    {
      "context": "Chat",
      "bindings": {
        "ctrl+e": "chat:externalEditor",
        "ctrl+u": null
      }
    }
  ]
}

Setting an action to null unbinds the default shortcut without assigning a replacement. Changes are detected and applied automatically — no restart, no /reload. Edit, save, and the new binding is live on your next keystroke.

Actions follow a namespace:action naming pattern — chat:submit, app:toggleTodos, history:search. The namespace tells you which context owns it. The 18 available contexts cover everything from Global (applies everywhere) down to narrow ones like DiffDialog, ThemePicker, and MessageSelector (the rewind/summarize dialog).

Chord Bindings

Chords are multi-key sequences separated by spaces — press one key, release, then press the next:

"ctrl+x ctrl+k": "chat:killAgents"

That's actually a default: Ctrl+X Ctrl+K stops all running background subagents in the current session. The default chord set also includes Ctrl+X Ctrl+E (open in external editor) and Ctrl+X Ctrl+B (background the current task, added in v2.1.169 specifically to dodge the tmux prefix conflict on plain Ctrl+B).

If you want to reclaim a prefix key for single-key use, you have to unbind every chord that uses it — a chord in any active context keeps the prefix reserved for chord-wait mode. To free up Ctrl+X as a plain newline shortcut, for example, you need to unbind all three defaults across two contexts:

{
  "bindings": [
    {
      "context": "Task",
      "bindings": { "ctrl+x ctrl+b": null }
    },
    {
      "context": "Chat",
      "bindings": {
        "ctrl+x ctrl+k": null,
        "ctrl+x ctrl+e": null,
        "ctrl+x": "chat:newline"
      }
    }
  ]
}

Changing the Submit Key

The most common rebind request: Enter submits, but you want Enter to insert a newline and something else to submit — the Slack/Discord pattern reversed. Do it by swapping what chat:submit and chat:newline point to:

{
  "bindings": [
    {
      "context": "Chat",
      "bindings": {
        "enter": "chat:newline",
        "ctrl+enter": "chat:submit"
      }
    }
  ]
}

Note the two reserved shortcuts you can't touch: Ctrl+C and Ctrl+D are hardcoded (interrupt and exit), and Ctrl+M is unusable because most terminals send an identical signal to Enter. Caps Lock isn't delivered to terminal apps at all, so it's not an option either.

Vim Mode Doesn't Fight Your Keybindings

Enable vim mode via /config → Editor mode, and it operates independently from the keybindings system. Vim mode handles input-level behavior — cursor motion, INSERT/NORMAL modes, standard vim commands. Keybindings handle component-level actions — submit, toggle todos, background a task.

The one place this matters in practice: in vim mode, Escape switches INSERT to NORMAL, it does not trigger chat:cancel. If you've rebound Escape expecting it to cancel the current operation, it won't fire while you're in INSERT mode. Most Ctrl+key shortcuts pass through vim mode fine and reach the keybinding system as normal. In vim NORMAL mode, ? opens the help menu and / opens history search — both vim-native behaviors, not remappable through the keybindings file.

Syntax Reference

Modifiers use + as a separator: ctrl/control, shift, alt/opt/option/meta (Alt on Windows/Linux, Option on macOS), and cmd/command/super/win (only detected in terminals that report the Super modifier — most don't, so stick to ctrl or meta for portable bindings).

A standalone uppercase letter implies Shift — K is the same as shift+k, which is what makes vim-style bindings like K for "jump up" vs. k for "move up one" work. But uppercase with a modifier is purely stylistic: ctrl+K and ctrl+k are identical.

Special keys: escape/esc, enter/return, tab, space, arrow keys (up/down/left/right), backspace/delete.

Terminal Multiplexer Conflicts

If you run Claude Code inside tmux, screen, or a similar multiplexer, a few defaults collide with your terminal's own prefix keys:

Ctrl+B   tmux prefix (press twice to send through to Claude Code)
Ctrl+A   GNU screen prefix
Ctrl+Z   Unix process suspend (SIGTSTP)

Claude Code's built-in validator flags these when the config loads. Start with --debug to see the full warning list — it also catches parse errors, invalid context names, reserved-shortcut conflicts, and duplicate bindings within the same context before they silently fail to apply.

A Practical Starting Config

If you're setting this up for the first time, this covers the highest-value changes without touching anything load-bearing:

{
  "$schema": "https://www.schemastore.org/claude-code-keybindings.json",
  "bindings": [
    {
      "context": "Chat",
      "bindings": {
        "ctrl+e": "chat:externalEditor",
        "meta+p": "chat:modelPicker"
      }
    }
  ]
}

Start small, run --debug to confirm it loaded clean, and layer in chords or a submit-key swap once the basics feel right. Because changes apply live, there's no cost to iterating — edit, save, test, adjust.

The Takeaway

Most Claude Code users never open keybindings.json because the defaults are good enough to get by. But if you're running it inside tmux, coming from a vim-heavy workflow, or just tired of Shift+Tab firing when you meant something else, the config file gives you full control — 18 contexts, chord support, and a validator that catches mistakes before they cost you a debugging session.

---

Want your team's Claude Code setup dialed in — keybindings, hooks, and permission modes configured for how you actually work? Our consulting team builds custom Claude Code workflows. Or start learning the fundamentals at Like One Academy.


Free: Claude custom instructions template pack

Eight copy-paste templates — developer, writer, analyst, CLAUDE.md starter, and more. Plus new guides in your inbox. No spam, unsubscribe anytime.

Or grab the templates directly — no email needed

Keep learning — for free

50+ AI courses. 590+ lessons. No paywall for starters.

Need help building this?

We build MCP servers, Claude workflows, and AI agents for teams. Strategy calls start at $150/hr.