How to Use WezTerm: A Beginner's Guide to the Lua-Powered Terminal
CodexFuse Team · 2026-10-30T13:20:59.348Z · 10 min read
Learn how to use WezTerm: install it on any platform, write your first Lua config, manage tabs and panes, multiplex without tmux, and SSH into remote servers.
Learning how to use WezTerm comes down to three moves: install the terminal, create one Lua config file (~/.wezterm.lua), and learn the default keybindings for tabs, panes, and the command palette. WezTerm is a free, open-source, cross-platform terminal emulator and multiplexer written in Rust by Wez Furlong — it runs on Linux, macOS, Windows 10, FreeBSD, and NetBSD, and it multiplexes terminal panes, tabs, and windows on local and remote hosts (wezterm.org). If you are a beginner switching from a plain terminal or from tmux, this guide walks you through install, your first launch, one minimal Lua config, panes and tabs, the built-in multiplexer, and SSH domains — all in one place. Before you connect to any remote server, generate a proper key pair with our free SSH key generator.
What is WezTerm?
WezTerm is a cross-platform terminal emulator and multiplexer implemented in Rust (wezterm.org). The "multiplexer" part is what sets it apart: like tmux or GNU Screen, WezTerm can manage multiple panes, tabs, and even remote sessions — but it does it natively, with a real Lua programming language for configuration instead of arcane dotfiles. It ships with ligatures, color emoji, font fallback, true color, dynamic color schemes, and clickable hyperlinks out of the box. For beginners, the practical difference is simple: instead of running a terminal plus tmux on top of it, WezTerm is one program that does both jobs, configured in a file you can read and edit like ordinary code.
How do I install WezTerm?
Download the stable build for your platform from wezterm.org/installation.html — stable is the right pick unless you need a feature that only exists in nightly. Pick exactly one of stable or nightly: the builds conflict and cannot live side by side.
Install WezTerm on macOS
Homebrew is the easiest route: run brew install --cask wezterm. For the nightly build, run brew install --cask wezterm@nightly (the old wezterm-nightly cask name was renamed, so uninstall it first if you have it). Nightly updates do not arrive through a normal brew upgrade — refresh it with brew upgrade --cask wezterm@nightly --greedy-latest (wezterm.org/install/macos.html). If you prefer the manual route, download the release zip, drag WezTerm.app to Applications, and on first launch right-click and choose Open to approve the downloaded app.
Install WezTerm on Linux
The official docs recommend native packages over the Flatpak sandbox: flatpak install flathub org.wezfurlong.wezterm works for a quick try, but sandboxed features behave slightly differently (wezterm.org/install/linux.html). On Debian/Ubuntu, add the APT repo, then install wezterm for stable or wezterm-nightly for nightly — one or the other, never both:
curl -fsSL https://apt.fury.io/wez/gpg.key | sudo gpg --yes --dearmor -o /usr/share/keyrings/wezterm-fury.gpg
echo 'deb [signed-by=/usr/share/keyrings/wezterm-fury.gpg] https://apt.fury.io/wez/ * *' | sudo tee /etc/apt/sources.list.d/wezterm.list
sudo apt update
sudo apt install wezterm
On Fedora and RPM-based systems, enable the Copr repo (sudo dnf copr enable wezfurlong/wezterm-nightly) and install; on Arch, sudo pacman -S wezterm plus the ttf-nerd-fonts-symbols-mono package for full glyph coverage.
Install WezTerm on Windows
Windows 10 build 17763 or later is required. Grab the setup.exe installer (installs to Program Files and registers itself on PATH) or the portable zip (wezterm.org/install/windows.html). Command-line users can run winget install wez.wezterm, scoop bucket add extras && scoop install wezterm, or choco install wezterm -y.
Where does the WezTerm config file live?
WezTerm looks for exactly one Lua config file, checking locations in a fixed order — and beginners most often lose an hour to editing the wrong file. The official recommendation is $HOME/.wezterm.lua on Linux and macOS (%USERPROFILE%/.wezterm.lua on Windows); multi-file setups belong at $XDG_CONFIG_HOME/wezterm/wezterm.lua (X11/Wayland) or $HOME/.config/wezterm/wezterm.lua (wezterm.org/config/files.html).
The full resolution order is: a --config-file command-line argument first, then the $WEZTERM_CONFIG_FILE environment variable, then (Windows only) the folder next to wezterm.exe, then $XDG_CONFIG_HOME/wezterm/wezterm.lua, then $HOME/.config/wezterm/wezterm.lua, and finally $HOME/.wezterm.lua as the last resort. Two practical consequences: if you have both ~/.wezterm.lua and ~/.config/wezterm/wezterm.lua, the .config one wins and your edits to the home-directory file will be silently ignored; and if your file has a Lua syntax error, WezTerm shows the error and runs on defaults rather than guessing. WezTerm watches the file it loaded and reloads automatically on save — or press Ctrl+Shift+R to force a reload.
How do I write my first WezTerm config in Lua?
Create ~/.wezterm.lua and paste this minimal starter. It pulls in the WezTerm API, builds a config object, and returns it — every config fragment you find online slots into this same shape:
-- ~/.wezterm.lua
local wezterm = require 'wezterm'
local config = wezterm.config_builder()
-- Font and size (adjust to your taste)
config.font = wezterm.font 'JetBrains Mono'
config.font_size = 14.0
-- Color scheme: wezterm ships with over 700 built-in schemes
config.color_scheme = 'Tokyo Night'
-- Breathing room around the window edges
config.window_padding = { left = 8, right = 8, top = 8, bottom = 8 }
-- Show the tab bar only when you have more than one tab
config.hide_tab_bar_if_only_one_tab = true
return config
Save the file and WezTerm applies it immediately — no restart needed, thanks to the auto-reload. A few beginner-friendly options to add next: config.initial_cols = 120 and config.initial_rows = 28 set the window geometry, config.font_size takes any point size, and config.color_scheme accepts any of the 700+ bundled schemes (the Lyz-Code Blue Book documents this collection). Because the file is real Lua, you can later graduate to conditionals (different settings per machine), functions, and split modules — the docs recommend an apply_to_config convention when your config outgrows one file.
What are the WezTerm keybindings I actually need?
WezTerm ships with sensible defaults you can list anytime with wezterm show-keys --lua (wezterm.org/config/default-keys.html). Learn this short list and you can do real work; everything else is in the command palette at Ctrl+Shift+P.
| Keys (Linux/Windows) | Keys (macOS) | Action |
|---|---|---|
Ctrl+Shift+T | Cmd+T | Open a new tab |
Ctrl+Shift+W | Cmd+W | Close the current tab (asks for confirmation) |
Ctrl+Shift+1..9 | Cmd+1..9 | Jump to tab by number |
Ctrl+Shift+Alt+" | Cmd+Shift+D* | Split the pane vertically |
Ctrl+Shift+Alt+% | Cmd+D* | Split the pane horizontally |
Ctrl+Shift+Left/Right/Up/Down | Opt+Arrow* | Move between panes |
Ctrl+Shift+Z | Cmd+Shift+Z* | Zoom the current pane to fill the tab |
Ctrl+Shift+P | Cmd+Shift+P* | Open the command palette |
Ctrl+Shift+L | Cmd+Shift+L* | Open the debug overlay |
Ctrl+Shift+Space | — | QuickSelect: click-free text selection |
Ctrl+Shift+X | — | Enter copy mode (keyboard text selection) |
* macOS Cmd-style splits are community conventions (John Lindquist's WezTerm Power User Guide) rather than defaults — on macOS the defaults still use the Ctrl+Shift variants above. The defaults are intentionally plain; most power users remap the splits to something easier to reach within their first week, which is a good second config project after the starter file. If you ever want a blank slate, config.disable_default_key_bindings = true turns all defaults off — but keep Ctrl+Shift+P assigned so you can always find your way back.
How does WezTerm's built-in multiplexer replace tmux?
WezTerm's answer to tmux is multiplexing domains: a domain is a distinct set of windows and tabs. When WezTerm starts it creates a default local domain, but it can also connect to additional domains — including ones on remote machines (wezterm.org/multiplexing.html). If you already live in tmux, read our tmux beginner guide for the comparison points: WezTerm gives you tmux-style persistence and pane management without a second program, and its configuration is Lua instead of tmux's command language.
The local multiplexer is already on: every tab and pane you open lives in the local domain. The payoff comes with remote work — see the SSH section below. One gotcha beginners hit: on a remote machine, the multiplexing flavor (SSHMUX:) only works if a compatible version of WezTerm is installed on the remote end; the plain SSH: flavor needs nothing on the server but won't give you detachable persistent sessions.
How do I connect to a remote server from WezTerm?
For an instant one-off connection, run wezterm ssh user@host (add :port for a non-standard port) — it behaves like the SSH client you already know. For servers you use daily, declare them once in your config as SSH domains and connect with one command:
config.ssh_domains = {
{
-- This name identifies the domain
name = 'my.server',
-- The hostname or address to connect to (matches your ssh config)
remote_address = '192.168.1.1',
-- The username to use on the remote host
username = 'wez',
},
}
Then run wezterm connect my.server — or skip the config entirely: since 2023, WezTerm automatically builds domains from your ~/.ssh/config file. Every Host entry becomes two domains: SSH:hostname for a plain SSH connection (works exactly like wezterm ssh) and SSHMUX:hostname for the multiplexing flavor that needs WezTerm on the remote end (wezterm.org/multiplexing.html). Find them without remembering any commands: press Ctrl+Shift+P, type part of the hostname, and pick the domain from the command palette (wezterm/wezterm discussion #3480).
Planning to self-host the servers you connect to? Our what is VPS hosting guide explains the machine side of that setup, and if you are comparing GPU-accelerated terminals with a different philosophy, our Ghostty beginner guide covers the zero-config alternative while the Warp beginner guide covers the AI-assisted one.
What should I configure next?
Once the starter config feels familiar, most beginners make two upgrades. First, a leader key for tmux-style bindings: one line like config.leader = { key = 'b', mods = 'CTRL', timeout_milliseconds = 1000 } turns Ctrl+B into a prefix key, so Ctrl+B then z zooms a pane — muscle memory that tmux users keep for free (John Lindquist's WezTerm Power User Guide). Second, custom keybindings that replace the awkward default split chords: the official docs show the full config.keys table format, and wezterm show-keys --lua prints your current bindings in paste-ready form so you can tweak one entry at a time instead of rewriting everything.
FAQ
Is WezTerm better than iTerm2 or Alacritty?
It depends on what you value. WezTerm's strengths are Lua configuration, the built-in multiplexer with SSH domains, and true cross-platform behavior — one config file works on macOS, Linux, and Windows. If you want a terminal that needs no configuration at all, read our Ghostty beginner guide; if you want AI baked into the terminal, read our Warp beginner guide.
Where do I put the WezTerm config on Windows?
Use %USERPROFILE%/.wezterm.lua — the same recommendation as $HOME/.wezterm.lua on other systems. Windows also supports a portable "thumb drive mode" that looks for wezterm.lua next to wezterm.exe, but the docs recommend it only when you actually run WezTerm from a thumb drive (wezterm.org/config/files.html).
Why is WezTerm ignoring my config changes?
Almost always, you are editing a file that WezTerm is not loading. Check the resolution order: $XDG_CONFIG_HOME/wezterm/wezterm.lua beats $HOME/.config/wezterm/wezterm.lua, which beats $HOME/.wezterm.lua. If the file that wins has a Lua error, WezTerm shows the error and runs on defaults — fix the syntax, save, and it reloads automatically.
Do I need WezTerm installed on my server to use SSH domains?
Only for the multiplexing flavor. The plain SSH:hostname domain works like an ordinary SSH client and needs nothing on the server. The SSHMUX:hostname flavor gives you persistent, detachable remote sessions but requires a compatible WezTerm build on the remote end (wezterm.org/multiplexing.html).
Should I install the stable build or the nightly?
Install stable unless you need a feature that only exists in nightly. You cannot keep both from the APT repo — the packages conflict — and the Homebrew nightly cask is named wezterm@nightly, upgraded with brew upgrade --cask wezterm@nightly --greedy-latest because a plain brew upgrade skips it (wezterm.org install docs, checked October 2026).
Sources
Facts and commands in this guide were verified against the official WezTerm documentation on 2026-10-30: the homepage (Rust implementation, supported platforms, multiplexer and feature list), Configuration (file locations, resolution order, auto-reload), Default Key Assignments (the keybinding table), Multiplexing (domains, SSH domain config, ~/.ssh/config auto-population), and the Linux, macOS, and Windows install pages (Flathub, APT repo, Homebrew casks, winget/scoop/choco). Community guides consulted for usage patterns: John Lindquist's WezTerm Power User Guide (leader key, macOS split conventions), the Bitdoze Mac setup guide (Nerd Font setup, starter config), the dev.to WezTerm + Neovim setup (minimal config shape), and the Lyz-Code Blue Book (700+ color schemes, APT repo setup).