Skip to content

zellij as first-class session backend: built-in resurrection, no plugins, cmd+q becomes safe by default #1518

@yigitkonur

Description

@yigitkonur

the opportunity

emdash's tmux wrapping (GEN-464, shipped in v0.4.25) was a great move — it made session persistence possible. but it's opt-in, requires tmux to be installed, and relies on tmux-resurrect + tmux-continuum for full resurrection after reboots. most users never toggle it on, which means most users still lose everything on cmd+q.

zellij has built-in session resurrection with zero plugins. if emdash adopted zellij as its session backend, process persistence would work out of the box — no opt-in toggle, no plugin dependencies, no configuration. cmd+q becomes a safe operation by default. no other agentic development environment does this today.

why zellij over tmux

capability tmux zellij
session resurrection requires tmux-resurrect + tmux-continuum plugins built-in, zero plugins
kitty keyboard protocol not supported (open pr #4068) supported — enables shift+enter in claude code, codex
scrollback serialization plugin-based, every 15min built-in, configurable interval
layout persistence format binary/opaque via plugin human-readable kdl files
auto-attach requires manual shell config built-in zellij attach --create
force close behavior kills session configurable: on_force_close "detach"
command restart on resurrection plugin handles it built-in --force-run-commands flag

the kitty keyboard protocol support is especially relevant — emdash users running claude code or codex through tmux-wrapped sessions currently can't use shift+enter and other extended key sequences. zellij supports these natively.

how it maps to emdash's architecture

emdash's current tmux wrapping creates sessions named emdash-{taskId}-{provider}. the same pattern works with zellij, but better:

local sessions

# current (tmux)
tmux new-session -d -s emdash-task123-claude 'claude'
tmux attach -t emdash-task123-claude

# proposed (zellij)
zellij attach --create emdash-task123-claude

zellij attach --create is idempotent — creates if new, reattaches if exists. no separate "detect existing session" logic needed in RemotePtyService.

remote sessions (ssh)

emdash already has a full ssh stack via ssh2 with connection pooling, keepalive pings, and exponential back-off reconnection. zellij integration on remote hosts:

  1. on first connection to a remote host, check for zellij: which zellij
  2. if missing, install the static binary: curl -sL https://github.com/zellij-org/zellij/releases/latest/download/zellij-$(uname -m)-unknown-linux-musl.tar.gz | tar xz -C ~/.local/bin/
  3. configure once: write ~/.config/zellij/config.kdl with on_force_close "detach" and session_serialization true
  4. every RemotePtyService session attaches to a zellij session named after the task

the cmd+q flow

today (without tmux toggle):

  1. user presses cmd+q
  2. disconnectAll() fires, ssh clients close, pty processes die
  3. on relaunch: layout restores from sqlite, but all running agents are gone

with zellij:

  1. user presses cmd+q
  2. disconnectAll() fires — but zellij sessions detach instead of dying (on_force_close "detach")
  3. on relaunch: emdash reconnects ssh, runs zellij attach --create emdash-{taskId}-{provider}, agent is still running exactly where it left off
  4. even after a full reboot: zellij resurrects sessions from its kdl cache files, offers to re-run the agent commands

this means a user can cmd+q at any point — mid-claude-code-task, mid-codex-run, mid-anything — and pick up exactly where they left off. no other tool in this space does this by default.

session metadata synergy

emdash already stores rich session metadata in sqlite (ssh_connections table, projects table with remote_path, worktree mappings). zellij adds a complementary layer:

what stored by survives
connection details, worktree paths, ui state emdash (sqlite) app restart
running processes, scrollback, pane layout zellij (kdl cache) app restart, ssh reconnect, reboot

together they give complete session resurrection — emdash knows where to connect and what the workspace looks like, zellij knows what was running and what the terminal output was.

zellij's layout system as workspace templates

emdash could generate .kdl layout files from its worktree configuration:

layout {
    tab name="agent" {
        pane command="claude" cwd="/home/user/project"
    }
    tab name="tests" {
        pane command="npm" args=["run", "test", "--watch"] cwd="/home/user/project"
    }
}

zellij action dump-layout can also capture any running session's layout on demand — useful for emdash's session export/import features (GEN-577).

the pitch

emdash is already the most complete agentic development environment out there. the one thing that still feels fragile is process persistence — and it doesn't have to be. zellij gives you:

  • cmd+q safety by default (not opt-in)
  • zero-plugin session resurrection (even across reboots)
  • kitty keyboard protocol (shift+enter, extended keys in agents)
  • human-readable session snapshots (kdl files you can version control)
  • idempotent session management (attach --create — one command, no detection logic)

this would make emdash the first tool where closing and reopening the app is genuinely seamless — your agents keep running, your scrollback is intact, your workspace is exactly as you left it. that's a killer differentiator.

related

  • GEN-464 — tmux wrapping (current implementation, could be extended to support zellij as an alternative backend)
  • GEN-584 — terminal replays buffered output on switch (zellij's viewport serialization handles this natively)
  • GEN-577 — active agent tab not persisted per-task (zellij layout files capture this)
  • community signal: grove demonstrates demand for zellij + worktree workflows

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions