I recently moved one of my Tauri apps (called lithographer) from v1 to Tauri 2.0. The app builds fine locally and in CI, but the AppImage refused to start properly on Arch Linux running Hyprland.
This post is about the issue I ran into and the fix I ended up with.
The Problem
After building the AppImage in GitHub Actions (on Ubuntu), it would not start cleanly on my Arch machine under Wayland. Symptoms were:
- Blank or gray window
Could not create default EGL display: EGL_BAD_PARAMETER- Protocol errors when talking to the Wayland display
The only way to make it work was to launch it like this:
DESKTOPINTEGRATION=1 LD_PRELOAD=/usr/lib/libwayland-client.so ./lithographer_0.1.0_amd64.AppImageThe problem is that libwayland-client.so lives in different locations depending on the distribution and desktop environment. On some systems it is in /usr/lib, on others /usr/lib64 or /usr/lib/x86_64-linux-gnu. Hardcoding one path is not reliable.
Tauri’s default linuxdeploy-plugin-gtk hook also forces GDK_BACKEND=x11, which pushes everything through XWayland and makes things fragile on modern Wayland setups.
The Fix
Instead of telling users to remember environment variables, I inject a small compatibility hook into the AppImage after it is built.
1. Wayland compatibility hook
I created src-tauri/appimage/apprun-wayland-compat.sh:
export DESKTOPINTEGRATION=1
if [ -z "${LD_PRELOAD:-}" ]; then
for lib in \
/usr/lib/libwayland-client.so \
/usr/lib64/libwayland-client.so \
/usr/lib/x86_64-linux-gnu/libwayland-client.so \
/usr/lib/aarch64-linux-gnu/libwayland-client.so \
/usr/lib/arm-linux-gnueabihf/libwayland-client.so; do
if [ -f "$lib" ]; then
export LD_PRELOAD="$lib"
break
fi
done
fiThis hook sets DESKTOPINTEGRATION=1 and tries several common locations for the Wayland client library. If the library is not found on the host, it simply does nothing.
2. Post-build patch script
I wrote src-tauri/scripts/patch-appimage-wayland.sh that does the following after tauri build:
- Finds the generated
*.AppDir - Copies the hook into
apprun-hooks/wayland-compat.sh - Patches the
AppRunscript so it sources the new hook before executingAppRun.wrapped - Repacks the AppImage using
linuxdeployfrom Tauri’s cache
After this step, the fix lives inside the AppImage. No external wrapper is needed at runtime.
Integrating the Fix
package.json
{
"scripts": {
"tauri": "tauri",
"tauri:build": "tauri build && bash src-tauri/scripts/patch-appimage-wayland.sh"
}
}For local builds that need the Wayland fix, I now run:
npm run tauri:buildCI wrapper script
I created scripts/tauri-build.sh at the root:
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$repo_root"
npm exec tauri "$@"
bash src-tauri/scripts/patch-appimage-wayland.shIn .github/workflows/build.yaml I point tauri-action at this wrapper:
- uses: tauri-apps/tauri-action@v0
with:
tauriScript: bash scripts/tauri-build.shThe rest of the workflow updates were straightforward:
- Switched runner to ubuntu-22.04
- Replaced old WebKit 4.0 packages with libwebkit2gtk-4.1-dev and friends
- Changed yarn install to npm install
- Added swatinem/rust-cache@v2
- Used actions/upload-artifact@v4 for the final .deb, .rpm, and .AppImage
Result
After these changes, the AppImage built by CI (or with npm run tauri:build locally) starts directly on Arch + Hyprland:
./lithographer_0.1.0_amd64.AppImageNo manual LD_PRELOAD or DESKTOPINTEGRATION needed.
Quick Reference / Manual Workaround
If you have an older unpatched AppImage, you can still force it with:
DESKTOPINTEGRATION=1 LD_PRELOAD=/usr/lib/libwayland-client.so ./lithographer_0.1.0_amd64.AppImage(Adjust the LD_PRELOAD path for your distro if needed.)
Other Notes
A few things that may still need attention on some setups:
- NVIDIA + Wayland users sometimes need
WEBKIT_DISABLE_DMABUF_RENDERER=1 - Some distributions benefit from
WEBKIT_DISABLE_COMPOSITING_MODE=1 - AppImages still require FUSE (or
--appimage-extract-and-run) - Building on Ubuntu 22.04 keeps glibc compatibility reasonable for most users
The .deb package is often more reliable on Arch because it uses the system WebKitGTK instead of the bundled one.
This approach has been working well for me. The hook is small, only activates when needed, and keeps the AppImage usable across different Wayland environments without forcing users to remember extra flags.
If you are hitting similar issues while moving a Tauri 2 app to AppImage on Linux, the pattern above should help.