Oct 24, 2026 • 3 min read
Automating Development Environments with Nix and Custom Zellij Layouts
Introduction
Setting up terminal development environments often requires repetitive manual steps: opening split panes, launching dev tools, and configuring terminal tabs. While traditional multiplexers rely on imperative shell scripts, Zellij uses declarative layout files written in KDL (KDL Document Language).
By embedding a custom Zellij KDL layout directly inside a Nix shell expression, you can generate a fully isolated, automated terminal workspace with a single command.
The full source code for this environment is available in the rosera/nix-shell-pack repository on GitHub.
The KDL Layout Definition (dev.kdl)
Zellij utilizes the KDL format to declare workspace tab templates, status bars, and split panes clean and human-readable.
Create a dev.kdl file to describe the split-pane arrangement:
layout {
default_tab_template {
pane size=1 borderless=true {
plugin location="zellij:tab-bar"
}
children
pane size=2 borderless=true {
plugin location="zellij:status-bar"
}
}
tab name="Go Dev" {
pane name="Dev" size="80%" focus=true {
command "zsh"
}
pane name="Build" size="20%" {
command "zsh"
}
}
}Wrapping the Layout in Nix (shell.nix)
Next, construct a shell.nix file. This Nix expression uses pkgs.writeText to read dev.kdl and pkgs.writeShellScriptBin to package a executable script (dev-zellij) that invokes Zellij directly with the custom layout file.
with import <nixpkgs> {};
let
# External Script: Reads './dev.kdl' and embeds it as a managed Nix store path
scriptZellijLayout = pkgs.writeText "dev.kdl" (builtins.readFile ./dev.kdl);
# Binary Wrapper: Generates 'dev-zellij' binary executable that runs Zellij with the layout
zellijLayout = pkgs.writeShellScriptBin "dev-zellij" ''
${pkgs.zellij}/bin/zellij --layout ${scriptZellijLayout}
'';
in
pkgs.mkShell {
name = "zellij-dev";
nativeBuildInputs = with pkgs; [
zellij
zellijLayout
];
LANGUAGE = "Zellij";
VERSION = "zellij --version";
shellHook = ''
# Optional: Script environment start up
echo "Welcome to $LANGUAGE Development Environment"
$VERSION
# Perform Zellij Dev Layout
exec dev-zellij
'';
}Running the Environment
You can spin up this development environment either from a local clone or directly from the remote repository URL.
Option 1: Running Locally
If you have cloned the repository, navigate to the development/nix-zellij directory and execute:
nix-shellOption 2: Running Directly from GitHub
Nix enables launching the shell directly from the remote archive without needing to clone the project manually:
nix-shell https://github.com/rosera/nix-shell-pack/archive/main.tar.gz -A development.nix-zellijUpon executing either command, Nix fetches zellij, builds the dev-zellij wrapper package, and launches the configured multi-pane layout instantly.
The Declarative Environment Lifecycle
[ nix-shell ]
/ \
/ \
v v
[ Zellij Package ] [ dev.kdl Path ]
\ /
\ /
v v
[ dev-zellij Executable ]
|
v
[ Managed Zellij Workspace ]- Evaluation:
nix-shellevaluatesshell.nix, importingzellijand convertingdev.kdlinto a store path usingbuiltins.readFile. - Execution: The
shellHookinvokesexec dev-zellij, executingzellij --layouttargeting the built KDL specification. - Session Isolation: Exiting the panes terminates the Zellij instance clean, returning you directly back to your host shell.
Conclusion
Combining Nix with Zellij’s declarative KDL layouts makes workspace management clean, predictable, and fully reproducible. By defining tool dependencies alongside workspace layouts in code, onboarding developers to a unified terminal configuration requires only a single nix-shell command.