Project
Compatibility
The platforms, tmux versions and shells that Glazier tests, and the tmux differences that you can see.
Every release of Glazier runs its end-to-end suite against six tmux versions in Docker, plus a weekly canary on tmux master. The matrix exists because tmux is not one program, it is six slightly different ones. A name that 3.3a stores as you typed it, 3.4 escapes twice when it prints it back. A layout that 3.5a prints as a coordinate string, 3.9 prints as JSON. An empty session name is fine on 3.2a, an error on 3.3a and fine again on 3.7c ( because of course it is ).
This page lists what the suite covers, so you know where you stand before you file an issue. The differences at the end are the ones that reach you as a user. The rest Glazier absorbs for you.
Platforms
Glazier runs on Linux and macOS, on amd64 and arm64. Each release includes a binary for each of the four combinations. See Installation for the packages.
Glazier does not support Windows, because tmux has no native Windows build.
To build Glazier from source, you need Go 1.26 or later and tmux on your PATH.
tmux versions
The end-to-end suite runs on these six targets. Each target is a Docker image with the tmux of that distribution, or with tmux built from source.
| Target | Base image | tmux |
|---|---|---|
jammy | ubuntu:22.04 | 3.2a |
bookworm | debian:bookworm-slim | 3.3a |
noble | ubuntu:24.04 | 3.4 |
trixie | debian:trixie-slim | 3.5a |
alpine | alpine:3.22 (musl) | 3.5a |
tmux37 | debian:bookworm-slim | 3.7c, built from source |
A seventh target, tmuxnext, builds tmux from its master branch. It runs each Monday as a canary and does not block a release. A change in tmux must not stop a release of Glazier, but Glazier must know about it before the change ships. tmux 3.9 changed its layout format this way, and the canary is green on it.
What the matrix does
The matrix runs every end-to-end case on every target. Each case runs the compiled glaze binary as a user does, then reads the result back with plain tmux commands. The suite never imports Glazier, so a bug in Glazier cannot hide in a check.
A baseline file lists the checks that are known to fail on a target, each with a reason. A check in the baseline that passes fails the run, so the baseline cannot go stale.
The release workflow runs the full matrix on the release zip before it publishes. A release ships only when the cases pass on each zip: linux/amd64 and linux/arm64 on all six targets, and darwin/arm64 on a macOS host. The darwin/amd64 zip has no runner of its own, so it shares its tests with darwin/arm64.
Shells
Glazier runs pane commands through a tmux paste buffer and one eval line, not through typed keys. The shell of the pane runs that line, so the shell matters. See Commands for the mechanism.
The suite tests these shells on every target:
| Shell | Form |
|---|---|
| bash | POSIX |
| zsh | POSIX, with a form of its own for eval |
| dash | POSIX |
| busybox ash | POSIX |
| fish | fish |
Glazier finds the shell from the tmux options default-command and default-shell. It also knows sh, ksh, mksh and yash as POSIX shells. For a shell that it does not recognise, Glazier uses the POSIX form and shows one warning. An exotic shell is out of scope by decision, not by accident.
Differences that you can see
Glazier gives the same result on every tmux version in the matrix. To do that, it has to work around a few differences, and some of them show up in your profile or in a warning.
Session names
tmux rewrites some characters when it creates a session. It rewrites ., : and a backslash on every version, and $ on 3.2a to 3.4. Glazier replaces all four characters with - before it calls tmux, on every version, and shows a warning with the new name. Thus the name in your profile and the name in tmux agree, and glaze down finds the session on every version. Window names and pane names keep the characters that you typed, except a backslash and control characters.
An empty session name
tmux 3.2a and 3.7c accept an empty session name. tmux 3.3a to 3.5a refuse it. Glazier rejects an empty name on every version. Leave out name to get the default session name default.
A $ in a name on tmux 3.4
tmux 3.4, and only 3.4, escapes a $ in a name a second time when it prints the name. Glazier removes the extra escape when it reads names back, so glaze ls and glaze save show the same name on every version. You do not have to do anything, but if you compare raw tmux list-windows output across versions, that is why it differs.
Layouts on tmux 3.9
tmux 3.9 and later print a window layout as JSON, for example {"V":2,"L":{"t":"h","w":80,"h":24,...}}. Older versions print a coordinate string, for example bb62,80x24,0,0. glaze save writes the form that your tmux prints, and glaze up accepts both forms. A profile with a JSON layout needs tmux 3.9 or later. To share a saved profile with users of an older tmux, replace the layout with a named preset such as tiled. See Window for the layout attribute.
Hook names
Glazier validates each hook name before it starts tmux. The list of valid names is the union of the hooks that tmux 3.2a to 3.7c report, so a profile that validates on one version validates on all of them. A hook that a later tmux adds is rejected until the list is rebuilt. An index such as after-new-window[1] is allowed. See Hooks and options.
Options
Glazier reads the option tables of your tmux once per up and sets each option at the scope where tmux keeps it. A window option on the session block, for example remain-on-exit, is set on every window. A session option on a window or pane block is set on the session, with a warning.