Building a Zellij Distribution
Zellij can be used as a library to build a distribution: a program of its own, based on Zellij, that bundles its own plugins, configuration, layouts and keybinding presets into a single executable.
Plugins bundled into a distribution behave exactly like Zellij's own built-in plugins:
- They are referred to as
zellij:<name>(eg. in layouts, keybindings and plugin aliases) - They are loaded from memory rather than from disk
- They are not subject to the plugin permission system
A minimal distribution
A distribution is a Rust program that depends on the zellij crate and calls zellij::run with a Distribution, instead of using the zellij binary:
[dependencies]
zellij = "0.46.0"
use zellij::{Distribution, DistributionLayout}; fn main() { zellij::run( Distribution::new("my-distribution", env!("CARGO_PKG_VERSION")) .with_display_name("My Distribution") .with_plugin("my-plugin", include_bytes!("../assets/my-plugin.wasm")) .without_plugin("share") .with_config(include_str!("../assets/config.kdl")) .with_layout(DistributionLayout::new( "my-layout", include_str!("../assets/layout.kdl"), )), ) }
With the bundled config.kdl:
plugins {
my-plugin location="zellij:my-plugin"
}
load_plugins {
"zellij:my-plugin"
}
default_layout "my-layout"
A complete example, including building the plugin from a build.rs, is in example/distribution in the Zellij repository.
zellij::run must be called at most once, before anything else in the process reads configuration. Stock Zellij itself is run with zellij::run_zellij().
The Distribution builder
| Method | Description |
|---|---|
Distribution::new(name, version) | The distribution's name and version. The name must be non-empty and may only contain lowercase letters, digits, - and _ |
with_display_name(name) | A human-readable name. Defaults to the name |
with_app_id(id) | The app id used by the desktop entry on Linux and the app bundle on macOS. Defaults to the name |
with_project_dirs(qualifier, organization, application) | The values the platform's configuration, cache, data and runtime folders are derived from. Defaults to ("", "", name). Only application matters on Linux, where it is lowercased |
with_plugin(name, bytes) | Bundle a plugin, loaded as zellij:<name> |
without_plugin(name) | Drop one of Zellij's built-in plugins. zellij:<name> then stops resolving |
without_builtin_plugins() | Drop all of Zellij's built-in plugins |
with_config(kdl) | Configuration applied on top of Zellij's defaults and below the user's own config.kdl |
with_layout(DistributionLayout) | A layout usable by name wherever a built-in layout name is accepted (--layout, default_layout, zellij setup --dump-layout). DistributionLayout::new(name, kdl).with_swap_layout(kdl) adds swap layouts |
with_keybind_preset(DistributionKeybindPreset) | A keybinding preset usable by name. DistributionKeybindPreset is in zellij_utils::distribution |
What the name changes
The name of a distribution names everything it owns, so it does not share files with Zellij or with other distributions:
- The configuration folder (eg.
~/.config/<name>on Linux) and the system configuration folder (/etc/<name>) - The cache, data and temporary folders, and the log file
- The plugin and data folders under
<prefix>/share/<name> - The command name shown in
--help
--version shows the distribution's version followed by the Zellij version it is built on, eg. 1.0.0 (zellij 0.46.0).
Replacing a built-in plugin
A bundled plugin cannot use the name of one of Zellij's built-in plugins, unless that built-in is dropped with without_plugin first. Dropping a built-in plugin does not remove the plugin alias that points to it: point that alias somewhere valid in the bundled configuration, or anything still using it (a keybinding, a layout) fails to load.
To leave the built-in alone and use a different implementation, give the bundled plugin its own name and point the alias at it:
plugins {
session-manager location="zellij:my-session-manager"
}
Zellij's default configuration refers to several built-in plugins, so a distribution using without_builtin_plugins() will almost certainly want to bundle its own configuration and layouts.
The built-in plugins are: bars, strider, session-manager, configuration, plugin-manager, about, share, multiple-select, layout-manager, prompt and context-menu.
Dropping built-in plugins does not make the executable smaller.
Builds without bundled plugins
When Zellij is built with the disable_automatic_asset_installation feature, no plugin bytes are bundled. Built-in plugins are then looked up as <name>.wasm in the plugin folder on disk instead.