Running the Buzz AppImage on NixOS
Last updated: July 29, 2026
I wanted to run the Buzz desktop AppImage on NixOS. programs.appimage does most of the work. Some WebKit/Tauri desktop apps still need more runtime libraries and GStreamer plugin paths in the AppImage FHS environment.
The original working notes are in oddship/nix-system. The deployed implementation was merged in oddship/nix-system@4c26fff. This page keeps the parts that I can reuse.
Enable AppImage support
For recent NixOS releases, enable AppImage support and binfmt registration:
programs.appimage = {
enable = true;
binfmt = true;
};
After this, you can launch executable AppImages directly:
You can also bypass binfmt and use the configured wrapper:
Add the missing runtime libraries
First, Buzz failed because it could not find a host library:
buzz-desktop: error while loading shared libraries: libzstd.so.1:
cannot open shared object file: No such file or directory
After adding pkgs.zstd, the next missing library was:
buzz-desktop: error while loading shared libraries: libelf.so.1:
cannot open shared object file: No such file or directory
That came from pkgs.elfutils.
The important lesson is that AppImages are not always fully self-contained. On NixOS, the AppImage runs in an FHS-like environment. That environment must contain the libraries that the binary expects to find on a conventional Linux system.
For Buzz, the useful package set also included common WebKit/Tauri desktop runtime packages:
programs.appimage.package = pkgs.appimage-run.override {
extraPkgs = pkgs: with pkgs; [
zstd
elfutils
webkitgtk_4_1
libsoup_3
glib-networking
libayatana-appindicator
];
};
Fix GStreamer discovery
After the ELF libraries were present, Buzz started. Then WebKit could not find GStreamer elements:
GStreamer element appsink not found. Please install it.
GStreamer element appsrc not found. Please install it
GStreamer element autoaudiosink not found. Please install it
Use GST_DEBUG=2 to see more detail:
GST_DEBUG=2
The plugins existed in the Nix store and in the generated FHS root. The problem was their location in the FHS environment. On this x86_64 system, they were under:
/usr/lib64/gstreamer-1.0
The default profile exposed /usr/lib/gstreamer-1.0 and /usr/lib32/gstreamer-1.0, but not /usr/lib64/gstreamer-1.0. Thus, WebKit's subprocess could not find plugin factories such as appsrc, appsink, and autoaudiosink.
The fix was to wrap appimage-run and set both GStreamer plugin path variables for AppImages only:
let
appimageRun = pkgs.appimage-run.override {
extraPkgs = pkgs: with pkgs; [
zstd
elfutils
webkitgtk_4_1
libsoup_3
glib-networking
libayatana-appindicator
gst_all_1.gstreamer
gst_all_1.gst-plugins-base
gst_all_1.gst-plugins-good
];
};
gstreamerPluginPath = lib.concatStringsSep ":" [
"/usr/lib64/gstreamer-1.0"
"/usr/lib/gstreamer-1.0"
"/usr/lib32/gstreamer-1.0"
];
in
{
programs.appimage = {
enable = true;
binfmt = true;
package = pkgs.symlinkJoin {
name = "appimage-run";
paths = [ appimageRun ];
buildInputs = [ pkgs.makeWrapper ];
postBuild = ''
wrapProgram $out/bin/appimage-run \
--set GST_PLUGIN_SYSTEM_PATH_1_0 lib.escapeShellArg gstreamerPluginPath \
--set GST_PLUGIN_PATH lib.escapeShellArg gstreamerPluginPath
'';
};
};
}
Keep this change in the appimage-run wrapper. If you set GST_PLUGIN_SYSTEM_PATH_1_0 globally, AppImage compatibility paths enter the whole desktop session. This can change the behavior of unrelated GTK or GStreamer applications.
Ghostty interaction
While Buzz was running, new Ghostty windows failed with OpenGL surface initialization errors:
ghostty: renderer=OpenGL
ghostty: failed to initialize surface err=error.SystemResources
ghostty: surface failed to initialize err=error.SurfaceError
This did not look like a missing library or Nix evaluation issue. It looked as if Ghostty's long-lived GTK single-instance process could not create another OpenGL surface while Buzz/WebKit was active.
The workaround was to disable Ghostty's GTK single-instance behavior:
programs.ghostty.settings = {
gtk-single-instance = false;
};
After you switch the NixOS configuration, stop the old Ghostty process once:
Useful checks
Inspect WebKit and GStreamer failures:
GST_DEBUG=2
Test if WebKit compositing is involved:
WEBKIT_DISABLE_COMPOSITING_MODE=1
Inspect desktop logs:
|
Build the configured AppImage wrapper, then inspect it:
One Nix flake rule: if the AppImage config is in a new module file, add it to Git before you run nix flake check. Otherwise, the flake cannot see it.