← All articles
TERMINAL TOOLS WezTerm: A GPU-Accelerated Terminal Configured in Lua 2026-03-04 · 4 min read · wezterm · terminal · terminal emulator

WezTerm: A GPU-Accelerated Terminal Configured in Lua

Terminal Tools 2026-03-04 · 4 min read wezterm terminal terminal emulator lua gpu acceleration multiplexer rust

WezTerm is a terminal emulator that takes the approach that your terminal should be as configurable as your text editor — using code, not a settings panel. Configuration is written in Lua, every behavior is programmable, and the multiplexer (tabs, panes, sessions) is built in rather than bolted on with tmux.

It's GPU-accelerated via wgpu, cross-platform (Linux, macOS, Windows), and handles ligatures and color profiles correctly without plugins.

Why Developers Switch to WezTerm

Installation

# macOS (Homebrew)
brew install --cask wezterm

# Linux (AppImage)
curl -LO https://github.com/wez/wezterm/releases/latest/download/WezTerm-ubuntu22.04.AppImage
chmod +x WezTerm-ubuntu22.04.AppImage
sudo mv WezTerm-ubuntu22.04.AppImage /usr/local/bin/wezterm

# Linux (Debian/Ubuntu package)
curl -fsSL https://apt.fury.io/wez/gpg.key | sudo apt-key add -
echo "deb https://apt.fury.io/wez/ * *" | sudo tee /etc/apt/sources.list.d/wezterm.list
sudo apt update && sudo apt install wezterm

# Arch Linux
yay -S wezterm

Basic Configuration

Create ~/.config/wezterm/wezterm.lua:

local wezterm = require 'wezterm'
local config = wezterm.config_builder()

-- Font
config.font = wezterm.font('JetBrains Mono', { weight = 'Regular' })
config.font_size = 14.0

-- Color scheme
config.color_scheme = 'Tokyo Night'

-- Window appearance
config.window_background_opacity = 0.95
config.macos_window_background_blur = 20
config.window_padding = {
  left = 12, right = 12,
  top = 8, bottom = 8,
}

-- Tab bar
config.enable_tab_bar = true
config.tab_bar_at_bottom = true
config.hide_tab_bar_if_only_one_tab = true

-- Scrollback
config.scrollback_lines = 10000

return config

Tabs and Panes

WezTerm's pane system is more flexible than tmux's because it's configured in Lua:

-- Default keybindings (or override them)
-- Ctrl+Shift+T   = new tab
-- Ctrl+Shift+W   = close tab
-- Ctrl+Shift+%   = vertical split
-- Ctrl+Shift+"   = horizontal split
-- Ctrl+Shift+Z   = zoom pane
-- Ctrl+Shift+←↑→↓ = move between panes

-- Custom keybindings
config.keys = {
  -- New tab with current directory
  {
    key = 't',
    mods = 'CTRL|SHIFT',
    action = wezterm.action.SpawnCommandInNewTab {
      cwd = wezterm.home_dir,
    },
  },
  -- Split horizontally
  {
    key = 'd',
    mods = 'CTRL|SHIFT',
    action = wezterm.action.SplitHorizontal { domain = 'CurrentPaneDomain' },
  },
  -- Navigate panes with vim keys
  {
    key = 'h', mods = 'CTRL|SHIFT',
    action = wezterm.action.ActivatePaneDirection 'Left',
  },
  {
    key = 'l', mods = 'CTRL|SHIFT',
    action = wezterm.action.ActivatePaneDirection 'Right',
  },
}

Leader Key (tmux-style)

If you use tmux bindings, WezTerm supports a leader key:

config.leader = { key = 'a', mods = 'CTRL', timeout_milliseconds = 1000 }

config.keys = {
  -- Leader + % = vertical split
  {
    key = '%',
    mods = 'LEADER',
    action = wezterm.action.SplitHorizontal { domain = 'CurrentPaneDomain' },
  },
  -- Leader + " = horizontal split
  {
    key = '"',
    mods = 'LEADER',
    action = wezterm.action.SplitVertical { domain = 'CurrentPaneDomain' },
  },
  -- Leader + z = zoom
  {
    key = 'z',
    mods = 'LEADER',
    action = wezterm.action.TogglePaneZoomState,
  },
  -- Leader + c = new tab
  {
    key = 'c',
    mods = 'LEADER',
    action = wezterm.action.SpawnTab 'CurrentPaneDomain',
  },
}

Status Bar with Dynamic Content

The status bar is programmatic — you can show git branch, clock, system info:

wezterm.on('update-status', function(window, pane)
  -- Git branch
  local cwd = pane:get_current_working_dir()
  local branch = ''
  if cwd then
    local cmd = 'git -C ' .. cwd.file_path .. ' branch --show-current 2>/dev/null'
    local handle = io.popen(cmd)
    if handle then
      branch = handle:read('*a'):gsub('%s+', '')
      handle:close()
    end
  end

  -- Time
  local time = wezterm.strftime('%H:%M')

  window:set_right_status(wezterm.format({
    { Foreground = { Color = '#a9b1d6' } },
    { Text = '  ' .. (branch ~= '' and ' ' .. branch or '') .. '  ' .. time .. '  ' },
  }))
end)

Multiplexer: Persistent Remote Sessions

WezTerm has a built-in multiplexer protocol that works over SSH, keeping sessions alive:

config.unix_domains = {
  { name = 'local' },
}

config.ssh_domains = {
  {
    name = 'homelab',
    remote_address = '192.168.1.10',
    username = 'hailey',
    multiplexing = 'WezTerm',
  },
}

Connect to a persistent session:

wezterm connect homelab

This is different from tmux — WezTerm syncs the window layout and renders remotely, so your tabs and splits persist even if the local connection drops.

Font and Ligature Setup

config.font = wezterm.font_with_fallback({
  'JetBrains Mono',
  'Nerd Font Symbols',
  'Noto Color Emoji',
})

-- Enable ligatures
config.harfbuzz_features = { 'calt=1', 'clig=1', 'liga=1' }

Popular fonts that work well: JetBrains Mono, Fira Code, Cascadia Code, Maple Mono.

Colorschemes

WezTerm includes 800+ built-in colorschemes:

-- List all schemes
wezterm list-fonts --list-system
-- (run in terminal)

-- Or browse at: wezfurlong.org/wezterm/colorschemes/

config.color_scheme = 'Catppuccin Mocha'  -- or 'Tokyo Night', 'Gruvbox Dark', etc.

Comparison to Alacritty and Kitty

Feature WezTerm Alacritty Kitty
Config language Lua (code) TOML Python (code)
Built-in multiplexer
GPU acceleration
Cross-platform Linux/macOS/Windows Linux/macOS/Windows Linux/macOS
Image protocol Sixel + iTerm2 Kitty protocol
Ligatures Experimental

Alacritty is the simplest and most minimal. Kitty is the most feature-complete on Linux/macOS. WezTerm is the best cross-platform option with the most programmable configuration.


Enjoyed this guide? Subscribe to DevTools Guide — a free weekly newsletter covering developer tools, workflows, and best practices.