Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

Helix User Guide

Generated June 2026 from helix-editor/helix at d3ec5bc

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Helix is a modal text editor for the terminal, written in Rust. Its editing model is heavily inspired by Kakoune and Neovim: you select first, then act. Helix ships with multiple-selection editing, built-in Language Server Protocol (LSP) support, smart incremental syntax highlighting via tree-sitter, and a debugger client — all configured through plain TOML files, with no plugins or external dependencies required to get started.

This guide takes you from installation through everyday editing, multi-cursor workflows, language-server features, configuration, and a complete keybinding and command reference.

Note

The Helix binary is named hx. A few package managers (notably Arch's extra repository) install it as helix instead. If hx is not found after installation, try helix.


Table of Contents

  1. Quick Start
  2. Installation
  3. Core Concepts
  4. Everyday Editing
  5. Multiple Selections
  6. Search and Replace
  7. Textobjects and Surround
  8. Working with Files, Buffers, and Splits
  9. Pickers and Fuzzy Finding
  10. Language Server Features
  11. The Command Line
  12. Shell Integration
  13. Registers and Macros
  14. Configuration
  15. Key Remapping
  16. Themes
  17. Configuring Languages and Language Servers
  18. Workspace Trust
  19. Migrating from Vim
  20. Troubleshooting
  21. Frequently Asked Questions
  22. Reference

1. Quick Start

If you just want to start editing immediately, here is the shortest path.

Tip

Helix ships with an interactive tutorial. Run hx --tutor (or :tutor from inside the editor) for a hands-on introduction. It is the single best way to learn the editing model, and most new users finish it in well under an hour.

Install, then open a file

macOS

brew install helix
hx myfile.txt

Linux (Fedora/RHEL)

sudo dnf install helix
hx myfile.txt

Windows

winget install Helix.Helix
hx myfile.txt

The five things to know first

You want to… Do this
Type text Press i to enter insert mode, then type. Esc returns to normal mode.
Move around In normal mode, use h j k l (or arrow keys) and w/b for words.
Save Type :w then Enter.
Quit Type :q then Enter (:wq to save and quit).
Open another file Press Space then f to open the file picker.

Important

Helix is modal. When you launch it you are in normal mode, where letter keys run commands instead of inserting text. To type literal characters you must first enter insert mode with i, a, o, or similar. If keys seem to "do strange things," you are almost certainly in normal mode — press Esc and try i.

Verify your setup

hx --health
Config file: default
Language file: default
Log file: ~/.cache/helix/helix.log
Runtime directories: ~/.config/helix/runtime
...

The health check reports where Helix looks for runtime files, your config, and which language servers and grammars are available. Run it any time something is not working as expected.


2. Installation

The recommended way to install Helix is through your operating system's package manager. For the latest nightly features you can build from source.

Note

To take full advantage of Helix you should also install the language servers for the languages you use (for example rust-analyzer for Rust, gopls for Go, typescript-language-server for TypeScript). See Configuring Languages and Language Servers and the Language Server Configurations wiki.

Package managers

Linux

Distribution Command Notes
Debian 13+ sudo apt install hx Older systems: follow Ubuntu/Mint below.
Ubuntu / Mint Install the .deb from the releases page
Fedora / RHEL sudo dnf install helix
Arch (extra) sudo pacman -S helix Run as helix, not hx. helix-git (AUR) builds master.
NixOS helix attribute in nixpkgs, or the project flake nix develop for a dev shell.
Flatpak flatpak install flathub com.helix_editor.Helix Run: flatpak run com.helix_editor.Helix.
Snap snap install --classic helix Installs as both helix and hx. Ensure /snap/bin is in PATH.
Homebrew (Linux) brew install helix

macOS

Method Command Notes
Homebrew brew install helix Latest release.
Homebrew HEAD brew install --HEAD helix Latest nightly.
MacPorts sudo port install helix

Windows

Method Command
Winget winget install Helix.Helix
Scoop scoop install helix
Chocolatey choco install helix
Packably packl install helix
MSYS2 pacman -S mingw-w64-ucrt-x86_64-helix

Pre-built binaries

Download a tarball from the GitHub Releases page. It contains an hx binary and a runtime directory.

  1. Add hx to your $PATH.
  2. Copy the runtime directory to a location Helix searches — a typical Linux/macOS location is ~/.config/helix/runtime.
# Example for a Linux/macOS tarball
mkdir -p ~/.config/helix
cp -r runtime ~/.config/helix/runtime

Tip

Run hx --health to see exactly which runtime directories Helix searches. You can override the default location by setting the HELIX_RUNTIME environment variable.

The Linux AppImage is another self-contained option:

chmod +x helix-*.AppImage
mkdir -p "$HOME/.local/bin"
mv helix-*.AppImage "$HOME/.local/bin/hx"   # ensure ~/.local/bin is in PATH

Building from source

Requirements:

  • The Rust toolchain
  • Git
  • A C++14-compatible compiler (GCC or Clang) to build the tree-sitter grammars
git clone https://github.com/helix-editor/helix
cd helix
cargo install --path helix-term --locked

For an optimized build tuned to your CPU:

cargo install \
   --profile opt \
   --config 'build.rustflags=["-C", "target-cpu=native"]' \
   --path helix-term \
   --locked

Either command creates the hx executable and compiles the tree-sitter grammars into the local runtime folder.

Important

When building from source you must point Helix at its runtime files. On Linux/macOS, either export HELIX_RUNTIME or create a symlink:

export HELIX_RUNTIME=~/src/helix/runtime          # add to ~/.bashrc
# or
ln -Tsf $PWD/runtime ~/.config/helix/runtime

On Windows, set HELIX_RUNTIME via setx HELIX_RUNTIME "%userprofile%\src\helix\runtime" or create a directory junction in %appdata%\helix\.

Note

If you use the musl-libc standard library, set RUSTFLAGS="-C target-feature=-crt-static" during the build so tree-sitter grammars load correctly. To skip grammar building entirely, set HELIX_DISABLE_AUTO_GRAMMAR_BUILD. You can fetch and build grammars later with hx --grammar fetch and hx --grammar build.

After building, validate the installation with hx --health.


3. Core Concepts

Helix's power comes from a small set of consistent ideas. Understanding them up front makes everything else feel natural.

Modes

Helix is a modal editor — different modes interpret your keystrokes differently.

Mode Enter with Purpose
Normal Esc (default) Navigation and editing commands. The default mode.
Insert i (and friends) Type text directly into the document.
Select / extend v Extend selections as you move, then act on them.

In addition, several minor modes are entered from normal mode for grouped commands: view (z), goto (g), match (m), window (Ctrl-w), and space (Space).

Selection-first editing

Inspired by Kakoune, Helix follows the selection → action model: you select what you want to act on (a word, a line, a paragraph) and then apply the action (delete, change, yank). This is the reverse of Vim's verb-then-object grammar.

A cursor is just a single-width selection. Whenever you move, you are really moving a selection — which is why every movement immediately shows you exactly what an action will affect.

Multiple selections

Multiple selections are a first-class, everyday tool — not an advanced feature. Instead of "find and replace all," the idiomatic Helix approach is to select every instance at once (one selection per match) and then edit them all simultaneously. See Multiple Selections.

Motions

Motions move the cursor or modify selections — w to the next word, f to find a character, gg to the top of the file. Because Helix is selection-first, motions in normal mode replace the selection, while the same motions in select mode extend it.


4. Everyday Editing

This section covers the bread-and-butter keys you will use constantly. The Reference contains the exhaustive tables; what follows is the working set.

Moving around

Key Moves to
h j k l Left, down, up, right (arrow keys also work)
w / b / e Next word start / previous word start / next word end
W / B / E Same, but for WHITESPACE-delimited "WORDs"
f<char> / t<char> Find / find-till the next <char> (not confined to the current line)
F<char> / T<char> Find / find-till the previous <char>
Alt-. Repeat the last f/t/m/[/] motion
Home / End Start / end of line
<n>G or <n>gg Go to line number <n>
Ctrl-d / Ctrl-u Half page down / up (moves cursor too)
Ctrl-f / Ctrl-b Full page down / up

Note

Unlike Vim, f, F, t, and T are not confined to the current line — they search across line boundaries.

Entering insert mode

Key Inserts…
i Before the selection
a After the selection (append)
I At the first non-blank of the line
A At the end of the line
o On a new line below
O On a new line above

Press Esc to return to normal mode. Changes are grouped into a single undo step per insert-mode session.

Making changes

Key Action
d Delete selection (yanks it to the default register)
c Change selection (delete and enter insert mode)
Alt-d / Alt-c Delete / change without yanking
r<char> Replace each selected character with <char>
R Replace selection with yanked text
~ Toggle case; ` to lowercase, Alt-` to uppercase
y / p / P Yank / paste after / paste before
> / < Indent / unindent
= Format selection (requires an LSP)
u / U Undo / redo
Alt-u / Alt-U Move backward / forward through edit history
. Repeat the last insert
J Join lines inside the selection
Ctrl-c Toggle comments on the selected lines
Ctrl-a / Ctrl-x Increment / decrement the number under the cursor

Tip

The "delete a word" muscle memory from Vim (dw) becomes wd in Helix: select the word first (w), then delete (d). Likewise cw → wc (or ec). See Migrating from Vim for a full mapping.

A first editing example

To change the word foo under your cursor to bar:

  1. w (or e) to select the word.
  2. c to change it — Helix deletes foo and enters insert mode.
  3. Type bar.
  4. Esc to return to normal mode.

5. Multiple Selections

Multiple selections are the defining Helix workflow. Master them and large edits become trivial.

Creating selections

Key Effect
s Select all regex matches inside the current selection(s)
S Split the selection into sub-selections on regex matches
Alt-s Split selection on newlines (one selection per line)
C / Alt-C Copy a cursor to the next / previous line (add cursor below/above)
% Select the entire file
x Select the current line; press again to extend to the next line
K / Alt-K Keep / remove selections matching a regex
, Collapse to just the primary selection
Alt-, Remove the primary selection
( / ) Rotate which selection is primary (backward / forward)
Alt-( / Alt-) Rotate the contents of the selections
& Align selections into columns
_ Trim whitespace from selections

The canonical "select all, edit all" workflow

To rename every occurrence of count to total across a file:

  1. % — select the whole file.
  2. s — open a regex prompt for selecting matches.
  3. Type count and press Enter — now every match is its own selection.
  4. c — change all selections at once; type total.
  5. Esc, then , to collapse back to a single cursor.

Tip

Use s to narrow within a selection and S to split a selection. Combine with Alt-s to put a cursor on every line, then A to append at the end of every line simultaneously — a fast way to add a trailing character (like ; or ,) to many lines.

Note

The status line shows the primary selection index out of the total number of active selections (for example 2/14), so you always know how many cursors are live.


6. Search and Replace

Helix has no dedicated :substitute command — search-and-replace is expressed through multiple selections.

Searching

Key Action
/ Search forward for a regex pattern
? Search backward
n / N Select the next / previous match
* Use the current selection as the search pattern, auto-wrapping word boundaries with \b
Alt-* Use the current selection as the search pattern verbatim

Search operates on the / register by default. The search prompt accepts full regular expressions. With editor.search.smart-case enabled (the default), a lowercase pattern is case-insensitive while a pattern containing an uppercase letter is case-sensitive.

Replacing across a selection

To replace foo with bar inside the current selection:

sfoo<ret>cbar<esc>,
  • s opens a regex prompt and selects every match inside the selection.
  • foo<ret> finalizes the matches (a cursor on each).
  • c changes them; type bar.
  • <esc> returns to normal mode; , keeps only the primary selection.

To do this for the whole file, prefix with % to select everything first:

%sfoo<ret>cbar<esc>,

Press Space then / to run a global search across the workspace folder. Results open in a fuzzy picker. After you jump to a result, press Space then ' to reopen the same results list.

Tip

The global search picker uses regex (not fuzzy matching). Press Enter without typing a filter to reuse the contents of the search register — for example * Space-/ Enter searches for the word currently under the cursor.


7. Textobjects and Surround

Textobjects

Textobjects let you select structured pieces of text — a word, a paragraph, or, with tree-sitter, a function or class.

  • mi<object> — select inside the object
  • ma<object> — select around the object
Key after mi/ma Selects
w / W Word / WORD
p Paragraph
(, [, ', … The specified surround pair
m The closest surround pair
f Function
t Type / class
a Argument / parameter
c Comment
T Test
x (X)HTML element

Note

The structural textobjects (f, t, a, c, T, x) require an active tree-sitter grammar and a textobject query file for the language. Coverage varies by language — see the language support matrix.

You can also navigate by textobject using the unimpaired bindings: ]f/[f for next/previous function, ]t/[t for next/previous type, and so on.

Surround

Helix has built-in surround support similar to vim-surround:

Key sequence Action
ms<char> (after selecting) Add surround characters to the selection
mr<from><to> Replace the closest surround pair
md<char> Delete the closest surround pair

Surround works with multiple selections too. To change every (use) to [use]:

  1. % to select the whole file.
  2. s, type use, Enter to put a selection on each match.
  3. mr([ to replace the parentheses with square brackets.

8. Working with Files, Buffers, and Splits

Buffers

Buffers are in-memory representations of open files. You can have many open at once.

Action Key / Command
Open a file :open <path> (:o, :e) or Space f
Next / previous buffer gn / gp, or :buffer-next / :buffer-previous
Switch buffers (picker) Space b
New scratch buffer :new
Close current buffer :buffer-close (:bc)
Last accessed file ga

Saving and quitting

Command Aliases Action
:write :w Save to disk (optional path argument)
:write! :w! Save, creating directories as needed
:update :u Save only if the buffer was modified
:write-all :wa Save all buffers
:quit :q Close the current view
:quit! :q! Close, discarding unsaved changes
:write-quit :wq, :x Save and close
:write-quit-all :wqa, :xa Save all and close all views
:reload :rl Discard changes and reload from disk

Splits (windows)

Press Ctrl-w to enter window mode, then:

Key Action
v Vertical split (right)
s Horizontal split (below)
h/j/k/l Move focus between splits
H/J/K/L Swap splits in a direction
q Close the current split
o Close all other splits

You can also open files directly into a split from the command line: :vsplit <path> (:vs) or :hsplit <path> (:hs, :sp). Launch Helix with --vsplit or --hsplit to open multiple files side by side from the shell.


9. Pickers and Fuzzy Finding

Pickers are interactive selection windows. Most are reached from space mode.

Picker Key
File picker (workspace root) Space f
File picker (working directory) Space F
Buffer picker Space b
Global search Space /
Document symbols (LSP/TS) Space s
Workspace symbols (LSP/TS) Space S
Diagnostics (document) Space d
Diagnostics (workspace) Space D
Jumplist Space j
Changed files (VCS) Space g
Command palette Space ?
Reopen last picker Space '

Within a picker, Tab/Shift-Tab (or arrow keys, or Ctrl-n/Ctrl-p) move between entries, Enter opens the selection, and Ctrl-s / Ctrl-v open it in a horizontal / vertical split. Ctrl-t toggles a preview. Esc closes the picker.

Most pickers use fzf-style fuzzy matching. When a picker has multiple columns you can target one column by prefixing its name with % (abbreviated to any prefix). For example, in the global search picker:

helix %p .toml !lang

searches for "helix" within files whose path ends in .toml but does not contain "lang".

Tip

Insert register contents into a picker query with Ctrl-r followed by a register name — for example Ctrl-r . inserts the current selection, and Ctrl-r % inserts the current file path.


10. Language Server Features

Helix has built-in LSP support. Install the language server for your language (see the wiki), make sure it is on your $PATH, and Helix uses it automatically for matching files.

Feature Key Command
Hover documentation Space k hover
Go to definition gd goto_definition
Go to type definition gy goto_type_definition
Go to references gr goto_reference
Go to implementation gi goto_implementation
Rename symbol Space r rename_symbol
Code action Space a code_action
Document symbols Space s lsp_or_syntax_symbol_picker
Workspace symbols Space S lsp_or_syntax_workspace_symbol_picker
Format selection = format_selections
Autocomplete (manual trigger) Ctrl-x (insert mode) completion
Next / previous diagnostic ]d / [d goto_next_diag / goto_prev_diag

Note

Mappings marked (LSP) in the keymap reference require an active language server, and those marked (TS) require a tree-sitter grammar for the file type.

Completion pops up automatically as you type (configurable). In the completion menu, Tab / Shift-Tab cycle entries, Enter accepts, and Ctrl-c rejects.

Useful LSP commands from the command line:

Command Action
:lsp-restart Restart the language server(s) for the current file
:lsp-stop Stop the language server(s) for the current file
:lsp-workspace-command Open the workspace command picker

Debugging (DAP)

Helix includes a Debug Adapter Protocol client. Debug commands live under Space G (experimental): Space Gl launches a debug target, Space Gb toggles a breakpoint, Space Gc continues, Space Gi/Space Go/Space Gn step in/out/over. You can also start a session from the command line with :debug-start (:dbg).


11. The Command Line

Press : to open the command line and run a typable command like :write or :open. The command line supports quoting, flags, and expansions.

Quoting

Arguments are split on spaces and tabs. Wrap an argument containing spaces in single quotes or backticks to keep it together:

:open 'a b.txt'

Double quotes behave the same but additionally expand their contents (see below). On Unix you can also escape a space with a backslash: :open a\ b.txt.

Flags

Flags modify command behavior, for example :sort --reverse (or -r). Type - to see completions for the current command's flags. Use -- to mark the end of flags so following arguments are treated literally: :open -- -a.txt.

Expansions

Anything beginning with % is an expansion — Helix replaces it before running the command. The general form is %[<kind>]<open><contents><close>, where the delimiters can be (), [], {}, <>, or the single characters ', ", |.

With no <kind>, the expansion is a variable:

Variable Expands to
%{cursor_line} Primary cursor line number (1-based)
%{cursor_column} Primary cursor column (grapheme clusters, 1-based)
%{buffer_name} Relative path of the current document
%{file_path_absolute} Absolute path of the current document
%{selection} Contents of the primary selection
%{selection_line_start} / %{selection_line_end} Primary selection start / end line
%{current_working_directory} Current working directory
%{workspace_directory} Nearest ancestor containing .git, .svn, .jj, or .helix
%{language} Language name of the current document
%{line_ending} The document's line-ending string

Other expansion kinds:

  • Shell — %sh{...} runs the contents through your shell and inserts the output. Example: :echo %sh{date}.
  • Unicode — %u{...} inserts a codepoint. Example: :echo %u{25CF} prints ●.
  • Register — %reg{a} inserts the contents of register a.
:echo %sh{git blame -L %{cursor_line},+1 %{buffer_name}}

Caution

Expansions are only evaluated when you press Enter. To use a literal % in a shell command, double it: :echo %sh{date -u +'%%Y-%%m-%%d'}.

Note

A few commands pass their argument straight to the shell and do not interpret quotes (though expansions still apply): :insert-output, :append-output, :pipe, :pipe-to, and :run-shell-command.


12. Shell Integration

Helix can pipe selections through external commands directly from normal mode.

Key Action
| Pipe each selection through a command, replacing it with the output
Alt-| Pipe each selection into a command, ignoring output
! Run a command, inserting its output before each selection
Alt-! Run a command, appending its output after each selection
$ Pipe each selection into a command; keep selections where it returned 0

For example, to sort and de-duplicate selected lines, pipe them through sort -u with |. To filter selections to only those that match a pattern, use $ with grep -q pattern.

The equivalent command-line forms are :pipe, :pipe-to, :insert-output, :append-output, and :run-shell-command (:sh, :!).

Tip

The shell used for these commands is the editor.shell setting — ["sh", "-c"] on Unix and ["cmd", "/C"] on Windows by default. Override it in your config if you prefer a different shell.


13. Registers and Macros

Registers

Registers store text and other data, much like a multi-slot clipboard. Select a register with " before an action — "ay yanks to register a, "op pastes from register o.

Default registers used when none is specified:

Register Contains
/ Last search
: Last executed command
" Last yanked text
@ Last recorded macro

Special registers:

Register When read When written
_ Returns nothing Discards everything (a "black hole")
# Selection indices (1, 2, …) Not writable
. Contents of the current selections Not writable
% Name of the current file Not writable
+ System clipboard Yanks to the system clipboard
* Primary (X11/Wayland) clipboard Yanks to the primary clipboard

Tip

Use the system clipboard directly via space mode: Space y yanks to the clipboard, Space p / Space P paste from it, and Space R replaces selections with its contents.

Macros

Key Action
Q Start / stop recording a macro to a register
q Replay a recorded macro from the selected register

Macros are experimental. To record into register a: "aQ, perform your edits, then Q again to stop. Replay with "aq.


14. Configuration

Helix is configured with a config.toml file in your config directory:

  • Linux / macOS: ~/.config/helix/config.toml
  • Windows: %AppData%\helix\config.toml

Tip

Open your config instantly with :config-open. After editing, apply changes with :config-reload (no restart needed). On Unix you can also reload by sending USR1: pkill -USR1 hx.

A typical starter config:

theme = "onedark"

[editor]
line-number = "relative"
mouse = false
cursorline = true
color-modes = true
bufferline = "multiple"

[editor.cursor-shape]
insert = "bar"
normal = "block"
select = "underline"

[editor.file-picker]
hidden = false

[editor.indent-guides]
render = true

Common everyday settings

Setting What it does Default
theme Color theme name (top-level key, not under [editor]) —
editor.line-number absolute or relative line numbers "absolute"
editor.mouse Enable mouse support true
editor.cursorline Highlight the line(s) the cursor is on false
editor.scrolloff Lines of padding kept around the cursor when scrolling 5
editor.bufferline Show a buffer bar: never, always, or multiple "never"
editor.color-modes Color the mode indicator differently per mode false
editor.true-color Force truecolor if your terminal isn't auto-detected false
editor.auto-format Format on save (also needs auto-format in languages.toml) true
editor.auto-save.after-delay.enable Auto-save after a delay false
editor.cursor-shape.{normal,insert,select} Cursor shape per mode (block, bar, underline, hidden) "block"

Note

The complete, every-key configuration reference — all [editor.*] subsections, statusline elements, gutters, soft-wrap, inline diagnostics, and more — lives in the Helix Admin Guide. This section covers the settings most users reach for first.

Project-local configuration

Place a config.toml and/or languages.toml inside a .helix/ directory at the root of a project. Those settings are merged on top of your global config and the built-in defaults, so you can tune behavior per repository.

my-project/
└── .helix/
    ├── config.toml
    └── languages.toml

Important

Loading project-local config and starting language servers can execute code defined by the repository. By default Helix protects you with Workspace Trust — you will be prompted before these features run in a new workspace.

You can also run Helix with a one-off config file: hx -c path/to/custom-config.toml.


15. Key Remapping

Helix supports one-way key remapping through config.toml. There are three kinds of things you can bind a key to:

  • Static commands — built-in commands like move_char_left (see the static command reference).
  • Typable commands — anything you can run from :, like :write.
  • Macros — a sequence of keys, written as a string starting with @.
[keys.normal]
C-s = ":w"                                   # Ctrl-s to save
C-o = ":open ~/.config/helix/config.toml"    # open your config
a = "move_char_left"                          # rebind a single key
"C-S-esc" = "extend_line"                     # Ctrl-Shift-Escape
g = { a = "code_action" }                     # 'ga' shows code actions
"ret" = ["open_below", "normal_mode"]         # run multiple commands in order
"A-x" = "@x<A-d>"                             # a macro: select line, delete without yank

[keys.insert]
j = { k = "normal_mode" }                     # 'jk' exits insert mode

Modifiers and special keys

Modifiers use the prefixes C- (Ctrl), S- (Shift), and A- (Alt); combine with a dash, e.g. C-S-esc. The Super/Windows/Command key is Meta-, Cmd-, or Win- (requires a terminal supporting the enhanced keyboard protocol).

Special key names include space, ret (Enter), esc, tab, backspace, del, ins, home, end, pageup, pagedown, left/right/up/down, and lt/gt for </>. Disable a key by binding it to no_op.

Note

Within a macro string, wrap modifier keys in angle brackets — <A-x>, <C-x> — to distinguish them from the literal letters A or C. Also, - cannot follow a modifier; write Alt + - as A-minus.

Defining your own minor modes

You can nest bindings to create custom minor modes:

# A new minor mode bound to '+'
[keys.normal."+"]
m = ":run-shell-command make"
c = ":run-shell-command cargo build"
t = ":run-shell-command cargo test"

16. Themes

Set a theme at the top of config.toml, or switch at runtime with :theme <name>:

theme = "catppuccin_mocha"

You can configure separate light and dark themes; on terminals that report a light/dark preference, Helix switches automatically:

[theme]
dark = "catppuccin_frappe"
light = "catppuccin_latte"
# fallback = "catppuccin_frappe"   # used if the terminal expresses no preference

Creating your own theme

Create ~/.config/helix/themes/mytheme.toml (or %AppData%\helix\themes\ on Windows) and reference it as theme = "mytheme". Each line styles one scope:

"ui.background" = { bg = "#1e1e2e" }
"keyword" = { fg = "mauve", modifiers = ["bold"] }
"ui.text" = "#cdd6f4"

[palette]
mauve = "#cba6f7"

Colors are CSS hex strings (#RGB or #RRGGBB) or names from the [palette]. You can extend an existing theme with inherits = "boo_berry".

Note

The names default and base16_default are reserved built-ins and cannot be overridden. Helix does not support transparency (no alpha channel). The full list of themeable scopes (syntax and UI) is documented in the Helix Admin Guide.


17. Configuring Languages and Language Servers

Language-specific behavior — which language server to use, indentation, formatters, file-type detection — is set in languages.toml. There are three locations, merged in order of increasing precedence:

  1. Built-in defaults (shipped with Helix).
  2. Your config directory: ~/.config/helix/languages.toml.
  3. Project-local: <project>/.helix/languages.toml.

Overriding a language

# ~/.config/helix/languages.toml
[[language]]
name = "rust"
auto-format = false
indent = { tab-width = 4, unit = "    " }

Commonly used [[language]] keys:

Key Description
name Language name (must match a known language)
file-types Extensions or globs that select this language
auto-format Format this language on save
comment-tokens Comment token(s), e.g. "//" or ["//", "///"]
indent { unit = " ", tab-width = 2 }
language-servers Which servers handle this language
formatter External formatter command (takes stdin, writes stdout)
roots Marker files used for LSP root detection (e.g. Cargo.toml)

Configuring a language server

[language-server.mylang-lsp]
command = "mylang-lsp"
args = ["--stdio"]
config = { provideFormatter = true }
environment = { "ENV1" = "value1" }

[[language]]
name = "mylang"
language-servers = ["mylang-lsp"]

A language can use multiple servers, and you can enable or disable individual features per server with only-features / except-features:

[[language]]
name = "typescript"
language-servers = [
  { name = "efm-lsp-prettier", only-features = ["format"] },
  "typescript-language-server",
]

File-type detection

file-types accepts plain extensions and glob tables (matched against the full path, always using / as the separator even on Windows):

file-types = ["toml", { glob = "Makefile" }, { glob = ".github/workflows/*.yaml" }]

Globs take priority over extension matches.

Tree-sitter grammars

Grammars are declared in [[grammar]] sections and fetched/built with hx --grammar fetch and hx --grammar build. To limit which grammars are processed, set a top-level use-grammars key before any [[language]] or [[grammar]] section:

use-grammars = { only = ["rust", "c", "cpp"] }
# or
use-grammars = { except = ["yaml", "json"] }

Tip

Change a single buffer's language on the fly with :set-language <name> (:lang). Run :lang with no argument to see the current language.


18. Workspace Trust

Because LSP and project-local configuration can execute code, Helix gates them behind a workspace trust mechanism. No workspace is trusted by default.

  • When you open a file in a new, undecided workspace, Helix prompts you about trust.
  • Choosing Never excludes the workspace so you are not prompted again.
  • :workspace-trust trusts the current workspace; :workspace-untrust revokes it.

Trusted and excluded workspaces are stored (newline-delimited) in ~/.local/share/helix/trusted_workspaces and .../excluded_workspaces.

Caution

You can restore the old, unguarded behavior — loading every .helix/config.toml and starting language servers without permission — by setting editor.insecure = true. Only do this if you understand the code-execution risk.


19. Migrating from Vim

The biggest adjustment is the selection → action order. In Vim you say "delete a word" (dw); in Helix you "select a word, then delete" (wd). Here are the most common translations:

Task Vim Helix
Delete a word dw wd
Change a word cw wc or ec
Delete a character x d (or ;d)
Delete an entire line dd xd
Copy a line yy Xy
Go to last line G ge
Go to line start / end 0 / $ gh / gl
First non-blank ^ gs
Jump to matching bracket % mm
Select whole file ggVG %
Comment lines gc Space c
Autocomplete Ctrl-p Ctrl-x
Global replace :%s/foo/bar/g %sfoo<ret>cbar<esc>,
Replace in selection :s/foo/bar/g sfoo<ret>cbar<esc>,
Reload file :e :reload
Run shell command :!cmd :sh cmd (or !cmd to insert output)

Note

Helix has no block-selection mode. Use multiple cursors instead: add cursors on lines below with C, then move them together. There are no named bookmarks; save a location to the jumplist with Ctrl-s and return via Ctrl-o / Ctrl-i or the jumplist picker (Space j).


20. Troubleshooting

The following entries combine Helix's documented behavior with real issues reported by the community.

Error: keys seem to insert random commands instead of text

Cause: You are in normal mode, where letter keys run commands. Solution: Press Esc to ensure you are in normal mode, then press i to enter insert mode before typing. Prevention: Watch the mode indicator on the status line (NOR, INS, SEL).

Error: hx: command not found

Cause: The binary is not on your $PATH, or your package manager installed it as helix (notably Arch's extra repository). Solution: Try running helix. Otherwise add the install location to $PATH. Verify with hx --health (or helix --health). Prevention: When using pre-built binaries or AppImages, install hx into a directory already on your PATH such as ~/.local/bin.

Error: syntax highlighting or indentation is missing

Cause: The tree-sitter grammar for the language isn't built, or runtime files aren't found. Solution: Run hx --health <language> to check. Fetch and build grammars with hx --grammar fetch && hx --grammar build, and confirm HELIX_RUNTIME points to a valid runtime directory. Prevention: When building from source, always configure the runtime directory (see Building from source).

Error: language server features (gd, hover, completion) do nothing

Cause: No language server is installed/on PATH, or the workspace is untrusted. Solution: Install the appropriate server and ensure it is on $PATH. Run hx --health to confirm Helix detects it. Trust the workspace if prompted (:workspace-trust). Restart the server with :lsp-restart. Prevention: Consult the Language Server Configurations wiki.

Error: some keybindings don't work in my terminal

Cause: Your terminal intercepts certain key combinations, or lacks support for the enhanced keyboard protocol (this affects Shift-Tab, Super-key bindings, and some Alt combinations).

Warning

A known long-standing example is Alt/Opt + _ not working on macOS (#2280). This is generally a terminal-level key-handling limitation rather than a Helix bug.

Solution: Check your terminal's key mappings for conflicts and, where available, enable the enhanced/Kitty keyboard protocol. See the Terminal Support wiki. Prevention: Prefer a terminal with good protocol support (e.g. Kitty, WezTerm, recent Alacritty/foot) for the smoothest binding experience.

Error: the editor crashed or panicked

Cause: Certain edge cases have produced panics — for example navigating the jumplist after :reload-all (#13149) or specific selection/change interactions (#12582). Several such cases have been fixed in recent releases. Solution: Update to the latest release or nightly. If it still reproduces, capture the log (hx -v for more verbosity, or :log-open) and file an issue with steps to reproduce. Prevention: Keep Helix current; many crash fixes ship in each release.

Error: opening a directory misbehaves

Cause: Passing a directory to hx opens the file picker / explorer; some platform edge cases have been reported (#14785). Solution: Open a specific file, or use Space f from within Helix. Update to the latest version.

Where is the log file?

Open it with :log-open, or start Helix with a custom path: hx --log /tmp/helix.log and tail -f /tmp/helix.log in another terminal. Increase verbosity with repeated -v flags (hx -vv).


21. Frequently Asked Questions

Q: Do I need to install plugins to be productive? No. LSP, tree-sitter syntax highlighting, multiple cursors, fuzzy pickers, and a debugger client are all built in. A formal plugin system is planned but not required for everyday use.

Q: How do I learn the editing model quickly? Run hx --tutor (or :tutor). It is an interactive, hands-on tutorial and the fastest way to internalize selection-first editing.

Q: How do I save and quit? :w saves, :q quits, :wq (or :x) does both. :wqa saves all buffers and closes all views.

Q: Why don't :%s/foo/bar/ and other :substitute-style commands exist? Helix expresses replacement through multiple selections: %sfoo<ret>cbar<esc>,. See Search and Replace.

Q: How do I copy to the system clipboard? Use space-mode clipboard commands: Space y to yank, Space p/Space P to paste. Or yank to the + register directly ("+y).

Q: How do I change the theme without editing my config? Run :theme <name> and use Tab to browse available themes interactively.

Q: Where do my config files go? ~/.config/helix/config.toml and languages.toml on Linux/macOS; %AppData%\helix\ on Windows. Project-local overrides go in a .helix/ folder.

Q: How do I reload my config without restarting? :config-reload. On Unix you can also send USR1: pkill -USR1 hx.

Q: Can I use Helix like a non-modal editor? Insert mode includes a few movement and editing keys (arrows, Ctrl-w to delete a word) for newcomers, but Helix is designed around modal editing and you will get the best experience by learning it. You can disable the insert-mode arrow keys once comfortable.

Q: How do I add a trailing character to many lines at once? x to select a line (repeat to extend), or % for the whole file, then Alt-s to split on newlines (a cursor per line), then A, type the character, Esc.

Q: How do I see every command and its keybinding? Open the command palette with Space ?, or consult the Reference below.

Q: What languages are supported? Several hundred, via tree-sitter grammars, with language-server support for most mainstream languages. See the language support matrix.

Q: My Alt/Shift/Super keybindings don't register — is Helix broken? Usually not. This is a terminal key-handling limitation. Enable the enhanced keyboard protocol in your terminal where possible, and check the Terminal Support wiki.


22. Reference

Command-line flags

hx [FLAGS] [files] — open files by passing paths. A path may include a position: file.rs:10:2 opens at line 10, column 2; +N file opens at line N; + opens at the last line.

Flag Description
-h, --help Print help
-V, --version Print version
--tutor Open the interactive tutorial
--health [LANG] Print health info (optionally for one language)
-g, --grammar fetch Fetch tree-sitter grammars
-g, --grammar build Build tree-sitter grammars
-c, --config <PATH> Use a specific config file
--log <PATH> Write the log to a specific path
-w, --working-dir <PATH> Set the initial working directory
--vsplit Open files in vertical splits
--hsplit Open files in horizontal splits
--strict Enforce strict parsing (fail on unknown config)
-v Increase verbosity (repeatable: -vv, -vvv)
-- Treat all following arguments as file paths

Keymap reference

Bindings marked (LSP) require a language server; (TS) require a tree-sitter grammar.

Movement (normal mode)

Key Command Key Command
h Left move left l Right move right
j Down move down (visual line) k Up move up (visual line)
w / b / e next/prev word start, next word end W / B / E same for WORDs
f / t find / till next char F / T find / till previous char
<n>G, <n>gg go to line <n> Alt-. repeat last motion
Ctrl-u / Ctrl-d half page up / down Ctrl-b / Ctrl-f page up / down
Ctrl-i / Ctrl-o jump forward / backward Ctrl-s save selection to jumplist
Home / End line start / end

Changes (normal mode)

Key Command Key Command
r replace char R replace with yanked
i / a insert before / after I / A insert at line start / end
o / O open line below / above . repeat last insert
u / U undo / redo Alt-u / Alt-U earlier / later in history
y / p / P yank / paste after / before "<reg> select register
> / < indent / unindent = format (LSP)
d / Alt-d delete / delete no-yank c / Alt-c change / change no-yank
Ctrl-a / Ctrl-x increment / decrement Ctrl-c toggle comments
~ / ` / Alt-` toggle / lower / upper case J join lines
Q / q record / replay macro

Selection manipulation

Key Command Key Command
s select regex matches S split on regex
Alt-s split on newlines & align in columns
_ trim whitespace ; collapse to cursor
Alt-; flip cursor/anchor , / Alt-, keep / remove primary
C / Alt-C add cursor below / above ( / ) rotate primary back / forward
Alt-( / Alt-) rotate contents back / forward % select whole file
x / X extend line below / to bounds Alt-x shrink to line bounds
K / Alt-K keep / remove matching regex J join lines
Alt-o / Alt-i expand / shrink syntax node (TS) Alt-p / Alt-n prev / next sibling (TS)

Minor-mode entry keys (normal mode)

Key Enters Key Enters
v select/extend mode g goto mode
m match mode : command mode
z / Z view / sticky view mode Ctrl-w window mode
Space space mode

Goto mode (g)

Key Goes to Key Goes to
g file start (or line <n>) e file end
h / l line start / end s first non-whitespace
d (LSP) definition y (LSP) type definition
r (LSP) references i (LSP) implementation
t / c / b window top / center / bottom a / m last accessed / modified file
n / p next / previous buffer . last modification
f file/URL under selection w jump to a two-char label

Space mode (Space) — pickers and LSP

Key Action Key Action
f / F file picker (root / cwd) b buffer picker
j jumplist picker g changed-file picker
s / S document / workspace symbols d / D document / workspace diagnostics
k (LSP) hover docs r (LSP) rename symbol
a (LSP) code action h (LSP) select symbol references
/ global search ? command palette
y / Y yank to clipboard / main to clipboard p / P paste clipboard after / before
R replace from clipboard ' last picker
c / C comment / block-comment w window mode

View mode (z / sticky Z)

Key Action Key Action
z/c center line t / b align top / bottom
j / k scroll down / up Ctrl-d / Ctrl-u half page down / up

Match mode (m)

Key Action
m go to matching bracket (TS)
s<char> surround add
r<from><to> surround replace
d<char> surround delete
a<object> / i<object> select around / inside textobject

Window mode (Ctrl-w)

Key Action Key Action
v / s vertical / horizontal split q / o close / close others
h/j/k/l move between splits H/J/K/L swap splits
w next window

Insert-mode keys

Key Action Key Action
Esc normal mode Ctrl-x autocomplete
Ctrl-r insert register Ctrl-w / Alt-Backspace delete previous word
Alt-d delete next word Ctrl-u / Ctrl-k delete to line start / end
Ctrl-s commit undo checkpoint Tab / Shift-Tab smart-tab / insert tab

Unimpaired (bracket) motions

Key Goes to Key Goes to
]d / [d (LSP) next / prev diagnostic ]f / [f (TS) next / prev function
]t / [t (TS) next / prev type ]a / [a (TS) next / prev argument
]c / [c (TS) next / prev comment ]T / [T (TS) next / prev test
]p / [p next / prev paragraph ]g / [g next / prev change
]Space / [Space add line below / above

Typable command reference

Run these from the command line (:). Aliases are shown after the canonical name.

Command Aliases Description
:quit :q Close the current view
:quit! :q! Force close, discarding changes
:open :o, :edit, :e Open a file
:write :w Write changes to disk (optional path)
:write! :w! Write, creating directories
:write-quit :wq, :x Write and close the view
:write-quit-all :wqa, :xa Write all and close all views
:write-all :wa Write all buffers
:quit-all :qa Close all views
:update :u Write only if modified
:new :n Create a new scratch buffer
:reload :rl Discard changes, reload from disk
:reload-all :rla Reload all documents
:buffer-close :bc, :bclose Close the current buffer
:buffer-next / :buffer-previous :bn / :bp Next / previous buffer
:format :fmt Format with formatter or LSP
:vsplit / :hsplit :vs / :hs, :sp Open file in vertical / horizontal split
:goto :g Go to a line number
:theme Change the theme (shows current if no name)
:set-option :set Set a config option at runtime
:toggle-option :toggle Toggle a config option
:get-option :get Read a config option's value
:set-language :lang Set the buffer's language
:config-open / :config-reload Open / reload your config
:config-open-workspace Open the workspace config
:log-open Open the Helix log file
:sort Sort ranges in the selection (--reverse to flip)
:reflow Hard-wrap selected lines to a width
:indent-style Set indentation (t for tabs, or 1–16 spaces)
:line-ending Set line ending (crlf / lf)
:encoding Set the file encoding
:earlier / :later :ear / :lat Jump back / forward in edit history
:clipboard-yank / :clipboard-paste-after System-clipboard yank / paste
:lsp-restart / :lsp-stop Restart / stop language servers
:lsp-workspace-command Open the workspace command picker
:pipe / :pipe-to :| Pipe selections to a shell command
:insert-output / :append-output Run a command, insert / append output
:run-shell-command :sh, :! Run a shell command
:tutor Open the tutorial
:change-current-directory :cd Change the working directory
:show-directory :pwd Show the working directory
:move :mv Move the buffer and its file to a new path
:read :r Read a file into the buffer
:set-register / :clear-register Set / clear a register
:character-info :char Info about the character under the cursor
:workspace-trust / :workspace-untrust Trust / untrust the current workspace
:cquit :cq Quit with an exit code
:redraw Re-render the whole UI
:echo / :noop Print to the statusline / do nothing

Note

This is the everyday subset. Every command also appears in the in-editor command palette (Space ?), which always reflects your exact version, including debugger (:debug-*) and tree-sitter inspection (:tree-sitter-*) commands.

Static command reference

Static commands are the building blocks you bind keys to (see Key Remapping). They number in the hundreds; below is an orientation by category. For the complete list with current default bindings, open the command palette (Space ?) or see the source static_commands! macro in helix-term/src/commands.rs.

Category Representative commands
Movement move_char_left/right, move_next_word_start, move_prev_word_end, goto_line
Extension (select) extend_char_left/right, extend_next_word_start, extend_to_line_bounds
Sub-word movement move_next_sub_word_start, move_prev_sub_word_end (unbound by default)
Changes delete_selection, change_selection, replace, undo, redo, indent
Selection select_regex, split_selection, keep_selections, align_selections
Syntax (TS) expand_selection, shrink_selection, select_next_sibling, match_brackets
Search search, search_next, global_search, search_selection
Clipboard/registers yank, yank_to_clipboard, paste_after, select_register, insert_register
LSP goto_definition, hover, code_action, rename_symbol, signature_help
Pickers file_picker, buffer_picker, command_palette, jumplist_picker
Windows vsplit, hsplit, jump_view_left, swap_view_down, wclose
Shell shell_pipe, shell_insert_output, shell_keep_pipe, suspend
Debugger (DAP) dap_launch, dap_toggle_breakpoint, dap_continue, dap_step_in
Misc no_op, increment, decrement, record_macro, replay_macro, goto_word

Language support

Helix supports several hundred languages through tree-sitter, with per-language capabilities that vary across syntax highlighting, tree-sitter textobjects, auto-indent, code navigation tags, rainbow brackets, and default language servers. A few examples:

Language Highlight Textobjects Auto-indent Default LSP
Rust ✓ ✓ ✓ rust-analyzer
C / C++ ✓ ✓ ✓ clangd
Go ✓ ✓ ✓ gopls
Python ✓ ✓ ✓ pylsp / ruff
TypeScript ✓ ✓ ✓ typescript-language-server
Bash ✓ ✓ ✓ bash-language-server

To see the full, version-accurate matrix for your build, consult the generated language support page in the Helix book, or run hx --health <language> for a specific language.