Zellij: Rust Terminal Workspace and Multiplexer
GitHub Repo
MIT
November 15, 2026 at 01:48 PM
0 views

Zellij: Rust Terminal Workspace and Multiplexer

@zellij-orgProject Author

What Zellij is

Zellij is a terminal workspace written in Rust. Its README describes it as "a workspace aimed at developers, ops-oriented people and anyone who loves the terminal" and adds that "similar programs are sometimes called 'Terminal Multiplexers'". In practice that means the familiar multiplexer job: split one terminal into panes and tabs, keep sessions running on a machine after the terminal that started them is gone, and reattach later from somewhere else. On top of that base the project has built a plugin system on WebAssembly, a KDL-based layout language, built-in session resurrection, a browser client and, in the latest release, its own desktop terminal window.

The design statement in the README is that "one must not sacrifice simplicity for power". The project aims at beginners and power users at the same time: an out-of-the-box experience with a status bar that shows the available keys, and underneath it "deep customizability, personal automation through layouts, true multiplayer collaboration, unique UX features such as floating and stacked panes, and a plugin system". The README also says the built-in web client makes "a terminal optional", and since 0.46.0 Zellij can run in its own window without another terminal emulator.

The repository was created on 1 September 2020, is MIT-licensed (copyright "Zellij contributors") and is developed on the main branch. The name comes from zellij, the hand-chiselled mosaic tilework of Morocco, Algeria and al-Andalus, a reference to panes fitted together into patterns.

How it works: sessions, panes, plugins

Client, server and the socket directory

Every Zellij session is a server process. Terminals, browsers and the desktop window are clients that attach to it. The FAQ explains the IPC model: the client-server contract uses protocol buffers, and session sockets live in a versioned directory, $XDG_RUNTIME_DIR/zellij/contract_version_1/ on Linux and macOS, with named pipes on Windows. Because the directory is versioned by contract rather than by Zellij release, the FAQ says sessions created by one Zellij version can be attached to by another "as long as the contract version remains the same", so upgrading the binary does not have to kill running sessions. Each session's socket is named after a 12-character hexadecimal id rather than the session name, and the FAQ tells script authors not to build socket paths from names but to use zellij list-sessions and zellij --session <name> action ... instead.

Panes, tabs, floating and stacked panes

The basic units are tiled panes inside tabs. Floating panes sit above the tiled layer and can be toggled, moved and resized; the FAQ notes that a floating pane can be embedded into the tiled layout and an embedded pane floated again. Stacked panes collapse several panes into a list of titles with one expanded, and 0.46.0 added horizontal stacks. "Swap layouts" let a tab snap to predefined arrangements as panes are opened and closed, for example two horizontal panes becoming three vertical ones when a third is opened.

Plugins on WebAssembly

The plugin documentation describes "a Webassembly / WASI plugin system". A plugin is "a first class citizen in the workspace, just like a terminal pane": it can render a UI, react to state changes and issue commands that control Zellij. Zellij builds its own UI from plugins (the tab bar, status bar, session manager, file picker, settings screen and others ship as built-in plugins, addressed with names like zellij:bars). The README says plugins can be written "in any language that compiles to WebAssembly", but the plugin docs are more precise: "Currently, Rust is the only language officially supported for plugins", with a community Go SDK listed as the one other option. Third-party plugins go through a permission system: events and commands are gated behind permissions such as ReadApplicationState, RunCommands, WriteToStdin and WebAccess, and a plugin has to ask the user to grant them. Built-in plugins get every permission.

Configuration in KDL

Configuration, layouts, themes and keybinding presets are all written in KDL. The config file is config.kdl in ~/.config/zellij (or a directory given by --config-dir or ZELLIJ_CONFIG_DIR), and the docs say Zellij watches the active file, so most changes apply without a restart. Since 0.46.0 most options can also be changed from a settings screen; when saving, Zellij edits only the affected parts of the file, keeps comments and copies the previous version to config.kdl.bak.

Key features

  • Two keybinding presets. The default preset reaches every mode from normal mode (for example Ctrl p for pane mode). The unlock-first preset starts locked and needs Ctrl g first, which the FAQ recommends when Zellij's shortcuts collide with other terminal apps. The default preset also contains a tmux mode, entered with Ctrl b, that mimics tmux-style keys (see the hands-on section).
  • Layouts as files. KDL layouts describe tabs, splits, commands and plugins; they can be loaded at start, added to a running session as new tabs, fetched from a URL (with every command held behind a "Waiting to run" banner) or swapped into a running tab with zellij action override-layout.
  • Session resurrection. Sessions are serialised to the cache folder, every 60 seconds by default, and can be brought back after a quit or crash. Commands are restored behind a "Press ENTER to run..." banner "to prevent uncomfortable accidents with things like rm -rf". Viewport and scrollback serialisation are opt-in.
  • A scriptable CLI. zellij action exposes what the docs call "100+ actions"; zellij run and zellij edit open commands and files in new panes; zellij subscribe streams rendered pane contents as text or NDJSON; zellij prompt shows a popup and prints the answer. The programmatic control page states that "no socket, HTTP API, or library binding is required".
  • Web client and remote attach. A built-in web server, off by default, serves sessions in the browser with token-based login, and zellij attach https://... attaches a local terminal to a remote session through it.
  • Multiplayer. Several clients can attach to one session; 0.45.0 allowed tabs to have different sizes when clients focus different tabs, and zellij watch opens a read-only view.
  • Inbox and attention tracking. Since 0.46.0 Zellij tracks per-pane states (needs you, failed, done, working, gone quiet, new output) across every session on the machine and gathers them in an inbox. Signals include the OSC 7501 program-status sequence, bells, OSC 9/777/99 notifications and OSC 133 prompt markers.
  • Nested sessions. Since 0.45.0, running Zellij inside a Zellij pane, typically over ssh, is handled explicitly: the inner session announces itself in-band and the outer one can zoom into it or route input to it.
  • Terminal features passed through. The compatibility page lists the kitty graphics protocol, Sixel (advertised only if the host terminal supports it), OSC 52 clipboard writes, OSC 7 working-directory reporting, grapheme clusters and horizontal scrolling.
  • The Zellij terminal. zellij terminal opens a native window on Linux (X11 and Wayland), macOS and Windows, with a tray icon, desktop notifications and a desktop app that keeps sessions running after the window closes.
  • Distributions. 0.46.0 lets Zellij be used as a Rust library to build a single-binary "distribution" with its own bundled plugins, config, layouts and keybinding presets.

Getting started

The installation docs list several routes. The quickest is the launch script, which downloads the latest release and starts it; on first run a setup screen offers to copy Zellij to a permanent folder. For bash or zsh:

bash <(curl -L https://zellij.dev/launch)

To compile from crates.io with Cargo (the README's own method; the docs add that this also installs a small zellij-terminal launcher):

cargo install --locked zellij

Or install a prebuilt binary through the cargo-binstall extension:

cargo binstall zellij

Prebuilt archives for Linux, macOS and Windows are on the releases page; on Windows there is an MSI installer and a zip. Many distributions also package Zellij, though the docs point out that third-party repositories are "not directly affiliated with zellij maintainers". After installing, a starting config can be generated:

mkdir ~/.config/zellij
zellij setup --dump-config > ~/.config/zellij/config.kdl

A basic layout from the docs, with one pane on top and a vertical split below running htop:

// layout_file.kdl

layout {
    pane
    pane split_direction="vertical" {
        pane
        pane command="htop"
    }
}

It is loaded with zellij --layout /path/to/layout_file.kdl; run from inside a session, the same command adds the layout as new tabs. For headless and scripted use, the CLI recipes page shows how to start a detached session and drive it:

zellij attach --create-background my-session
zellij run -- git diff
zellij run --notify -- cargo build

Shell completions, including the zr, zrf and ze aliases for running and editing in new panes, come from zellij setup --generate-completion bash (or zsh, fish).

Hands-on: Zellij 0.46.0 in a headless VM

The following was run on 15 November 2026 on a 2-vCPU Linux x86_64 cloud VM (Ubuntu 24.04.5 LTS), with no desktop and no attached terminal. Instead of compiling with Cargo, the prebuilt zellij-x86_64-unknown-linux-musl.tar.gz archive for v0.46.0 was downloaded from the GitHub release, following the docs' binary-download route, and its SHA-256 checked against the published checksum file. All sessions were background sessions controlled through the CLI. This is a smoke test, not a benchmark.

Command or checkResult (trimmed)
Release archive38.9 MB tarball holding one file, zellij: 88,861,456 bytes, a stripped static-pie ELF; SHA-256 matched the release's .sha256sum
zellij --versionzellij 0.46.0
zellij setup --check[Version]: "0.46.0", config dir and config file "Not Found" (fresh home), cache dir ~/.cache/zellij, plugin dir ~/.local/share/zellij/plugins with the note "Builtin, default plugins will not be loaded from disk", [DEFAULT EDITOR]: Not set, [FEATURES]: []
zellij setup --dump-config | wc -l1,083 lines of commented KDL, starting with an explanation of keybinding presets (keybinds preset="default" primary="Ctrl" secondary="Alt")
zellij setup --dump-layout defaultA 9-line layout: a one-row borderless tab-bar plugin pane, one terminal pane, and a one-row status-bar plugin pane
zellij setup --dump-keybinds defaultIncludes a tmux mode reached with {primary} b (Ctrl b by default), where " and % open panes down and right, z toggles fullscreen, c opens a tab and [ enters scroll mode
zellij list-sessions (nothing running)No active zellij sessions found., exit code 1
zellij attach --create-background demoReturned in 0.14 s, exit code 0; zellij list-sessions --no-formatting then showed demo [Created 2s ago]
zellij --session demo action list-tabs --jsonOne tab, "name": "Tab #1", "active_swap_layout_name": "BASE", a 50x50 display area and an attention block with counts for needs_you, failed, done, working and quiet
zellij --session demo action list-panesplugin_4 (plugin, "Welcome to Zellij"), terminal_0 (the shell); the JSON form adds geometry, command state and attention fields per pane
zellij --session demo run --name uname -- uname -smPrinted the new pane id terminal_1; action dump-screen --pane-id terminal_1 showed Linux x86_64
action new-pane --block-until-exit-success --name build -- sh -c '...'Blocked for 1.0 s until the one-second command exited 0, then returned exit code 0
action paste then action send-keys ... "Enter" into terminal_0dump-screen showed the typed echo hello from zellij and its output
action dump-layoutKDL for the live session, including the two command panes with their args and start_suspended true, and the floating "Welcome to Zellij" pane running zellij:configuration with is_setup_wizard "true"
Server memoryAbout 48 MB resident (RSS) for an idle background session, one measurement
kill-session demo, then list-sessionsdemo [Created 1s ago] (EXITED - attach to resurrect); the saved layout was at ~/.cache/zellij/contract_version_1/session_info/2d7e1f9d660a/session-layout.kdl (372 lines), next to session_index.sqlite
delete-session demoSession: "demo" successfully deleted.
zellij web --daemonize, --status, --stopWeb Server started on 127.0.0.1 port 8082; status reported Web server online with version: 0.46.0; a request to http://127.0.0.1:8082/ returned HTTP 200 text/html; Stopped web server.
zellij web --create-tokenCreated token successfully followed by token_1: <token>; --list-tokens showed only the name and creation time

Three observations from the run. First, a fresh home directory starts with the first-run setup wizard open as a floating plugin pane, even in a headless session; scripts that count panes should expect it (or ship a config file). Second, setup --check printed an empty [FEATURES] list, yet the web server in the same binary started and served pages, so that line is not a reliable way to tell whether the web capability is compiled in. Third, the attempt to combine --create-token with --token-name failed with "the argument '--create-token' cannot be used with one or more of the other specified arguments", even though --help lists --token-name as "Optional name for the token"; plain --create-token worked.

Scripting and agent workflows

The docs give a lot of space to driving Zellij from other programs. The programmatic control page lays out a create, command, observe, react loop. Create and run commands return ids on stdout (terminal_1, plugin_4), input can be sent by pane id with write-chars, paste or send-keys, and output can be read either as a snapshot with dump-screen or as a stream with zellij subscribe --format json. Blocking flags on new-pane wait for a pane to close, for its command to exit, or specifically for success or failure, which turns a pane into a step in a shell pipeline. The hands-on run above exercised exactly that loop.

Two newer features target coding agents directly. The inbox integration page, last checked by the project on 9 November 2026, lists agents that report their status to Zellij over OSC 7501 with no setup, including Claude Code, Codex CLI (see the Codex CLI page), OpenCode 2.1.0 and later, GitHub Copilot CLI, Qwen Code and goose. Gemini CLI is listed as not yet reporting status; the page suggests turning on its notifications so it at least shows as "needs you". The second feature is zellij action set-resurrect-command, added in 0.46.0, which lets a program tell Zellij how to restart it after resurrection; the docs' own example restores an OpenCode session by id. Paired with a worktree manager such as Worktrunk, whose README demo shows several agents running in Zellij tabs, this makes Zellij a plausible control room for parallel agent sessions on one machine.

How Zellij compares

The obvious comparison is with tmux and GNU screen, the long-established terminal multiplexers that the README's "terminal multiplexers" label points to. All three keep sessions alive on a server and let clients detach and reattach. Zellij's sources do not compare it with either, so the differences below are limited to what Zellij documents about itself: a discoverable status bar and presets instead of a single prefix key, built-in resurrection, layouts as declarative KDL files, WebAssembly plugins with permissions, a built-in browser client, JSON output for scripting and a desktop window. Zellij does not document reading tmux or screen configuration files, so moving over means rewriting bindings and session scripts. tmux and screen have been around far longer and are typically available from a distribution's standard packages, an advantage a newer tool has to earn. Former tmux users get some help: the default keybinding preset includes a tmux mode on Ctrl b.

ToolKindHow it relates to Zellij
ZellijTerminal workspace / multiplexer with its own optional window and web clientSessions, panes, tabs, KDL layouts, WASM plugins, resurrection, CLI with JSON output
tmuxTerminal multiplexerSame core job (persistent sessions, panes, detach and reattach); older and widely deployed. Zellij's default preset ships a tmux mode on Ctrl b with tmux-style keys, but no config-file compatibility
GNU screenTerminal multiplexerThe oldest of the three for the same job; Zellij's docs do not discuss it
rmuxRust terminal multiplexer pitched at agent workflowsOverlaps with Zellij's newer agent-oriented features; not tested here, see its page for specifics
GhosttyTerminal emulatorIts README lists multi-window, tabbing and splits on macOS and Linux. That covers local window management but not persistent server-side sessions; Zellij can run inside it
TabbyTerminal emulator plus SSH and serial clientIts README lists split panes, remembered tabs and an SSH connection manager; Zellij instead keeps sessions alive on the host and attaches to them

The terminal emulators in the table are not really competitors: Zellij runs inside any of them, and its FAQ suggests the Zellij terminal mainly as a fix when a host terminal mishandles keys, clipboard or fonts. The choice that matters is between multiplexers. For a server where only stock packages are allowed, or a team with years of tmux scripts, tmux remains the low-friction answer. For someone who wants panes, layouts and persistent sessions to work without first writing a config file, or who wants to script a workspace through JSON output, Zellij is the more complete package.

When not to use Zellij: limits and trade-offs

  • A large binary. The Linux musl release binary tested here is about 89 MB. The default build bundles the web server, the desktop terminal and the built-in plugins. The install docs show a cargo install invocation with --no-default-features that leaves the terminal feature out.
  • Keybinding collisions. The default preset grabs a number of Ctrl combinations. The FAQ's first entry is about this and points to the unlock-first preset or changed modifiers. Expect some retraining either way.
  • Fonts and terminal quirks. The FAQ and compatibility pages list broken status-bar glyphs without a Nerd Font (zellij options --simplified-ui true is the workaround), the macOS Alt key, clipboard setup, mouse issues and odd colours in some apps. Since 0.45.0 programs inside panes get an empty clipboard when they try to read it through OSC 52.
  • Plugin language reality. Despite the "any language that compiles to WebAssembly" line in the README, Rust is the only officially supported plugin language. 0.46.0 also broke parts of the zellij-tile plugin API (Text::new became Text::from), so plugin authors should expect to follow releases.
  • Web server exposure. The web client requires HTTPS when listening on anything other than 127.0.0.1, unless the dangerously_allow_web_serving_without_a_certificate option is set. The docs say the server "does not provide its own rate-limiting" and recommend a reverse proxy for untrusted networks; authenticated users are treated as fully trusted because they get a shell as the server's user.
  • Resurrection is not process persistence. Resurrection restores the layout and re-runs detected commands; it does not bring back the state of the processes themselves. Command detection can be wrong for wrapped commands, which is why post_command_discovery_hook and set-resurrect-command exist. Serialising scrollback can grow the cache folder.
  • Desktop features need a desktop. The Zellij terminal needs DISPLAY or WAYLAND_DISPLAY on Linux. Over SSH, in containers or in WSL, the desktop integration is not offered.
  • Fast-moving feature set. 0.45.0 (20 August 2026) and 0.46.0 (11 November 2026) each added major surfaces: mobile web UI, nested sessions, kitty graphics, then the desktop window, inbox and distributions. The [Unreleased] section already lists fixes for the new inbox, web client and desktop app. Teams that prize stability may want to trail releases.
  • Issue triage. The README says maintainers "do their best" to reply to issues "but unfortunately cannot promise these will always be dealt with or even read", and warns against installing from main, which "may corrupt the cache for future versions".

What changed in 0.46.0

Version 0.46.0, released on 11 November 2026, is the largest recent release by changelog length. Headline items: the terminal window (desktop client) on macOS, Linux and Windows, with a tray, notifications and a setup screen that can install Zellij.app on macOS or copy the binary to ~/.local/bin; the inbox with cross-session activity notifications and OSC 7501 support; a right-click menu, interactive configuration, popups and notifications; mouse reordering of tabs and configurable mouse bindings; horizontal stacks; runtime hiding of the tab bar and status bar; set-resurrection-command for programs; using Zellij as a library for distributions; and a performance item to "improve output/stdout/scrolling speed". Fixes cover grapheme clusters, wide CJK characters, resize correctness, resurrection layout corruption and a race when two servers start with the same name. The 0.45.x line before it added the PWA and mobile web UI, nested-session handling, kitty graphics, OSC 133 support and starting sessions with an initial command (zellij attach -a my-session -- htop).

Project activity

Checked 15 November 2026: latest release v0.46.0 (11 November 2026, per the changelog), MIT licence, about 36,100 stars on the zellij-org/zellij repository, last push 13 November 2026. The project is written in Rust (the workspace declares a minimum Rust version of 1.95), was created on 1 September 2020 and develops on main. Documentation, screencasts and tutorials are at zellij.dev, with the documentation sources kept in the zellij-org.github.io repository. The community uses Discord and the Matrix room #zellij_general:matrix.org. The README lists G-Research and codo.tech as sponsors.

Enjoying this project?

Discover more amazing open-source projects on TechLogHub. We curate the best developer tools and projects.

Project
zellij
Created
November 15
Last Updated
November 15, 2026 at 01:48 PM

Maintain Zellij: Rust Terminal Workspace and Multiplexer? Add the badge to your README

Show that the project is featured on TechLogHub and send readers to this write-up.

Featured on TechLogHub
[![Featured on TechLogHub](https://techloghub.com/badge-neutral.svg)](https://techloghub.com/open-source/zellij?utm_source=techloghub_badge&utm_medium=referral&utm_campaign=readme)

Find more projects like this

One email a week: new and trending developer tools, fresh comparisons, and what shipped. Unsubscribe in one click.