Tauri 2.0 AppImage EGL Issue on wayland

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:

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.AppImage

The 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
fi

This 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:

  1. Finds the generated *.AppDir
  2. Copies the hook into apprun-hooks/wayland-compat.sh
  3. Patches the AppRun script so it sources the new hook before executing AppRun.wrapped
  4. Repacks the AppImage using linuxdeploy from 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:build

CI 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.sh

In .github/workflows/build.yaml I point tauri-action at this wrapper:

- uses: tauri-apps/tauri-action@v0
  with:
    tauriScript: bash scripts/tauri-build.sh

The 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.AppImage

No 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:

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.