How to run pywebview (Qt backend) on NixOS.

Why

pywebview's Qt backend uses prebuilt wheels (PyQt6 + QtWebEngine). On NixOS they can't find the shared libraries they expect, so the libraries have to be exposed through LD_LIBRARY_PATH.

The shell.nix below includes everything QtWebEngine/Chromium needs, so it works on a fresh NixOS install with nothing else installed.

shell.nix

{ pkgs ? import <nixpkgs> { } }: let runtimeLibs = with pkgs; [ # Base stdenv.cc.cc.lib zlib zstd brotli # GL / graphics libGL libglvnd # libEGL libgbm libdrm vulkan-loader # Wayland / input wayland libxkbcommon # X11 libx11 libxext libxrandr libxcomposite libxdamage libxfixes libxrender libxi libxcursor libxtst libxkbfile libxshmfence # xcb libxcb libxcb-util libxcb-cursor libxcb-wm libxcb-image libxcb-keysyms libxcb-render-util # GTK stack / fonts glib gtk3 gdk-pixbuf pango cairo atk at-spi2-atk harfbuzz fontconfig freetype # QtWebEngine / Chromium dbus expat nss nspr cups alsa-lib libpulseaudio krb5 icu libpng libjpeg libwebp libxml2 libxslt lcms2 libopus libevent minizip snappy ]; in pkgs.mkShell { packages = [ pkgs.uv ]; LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath runtimeLibs; # --pure sets this to a nonexistent file, which breaks httpx SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; QTWEBENGINE_DISABLE_SANDBOX = "1"; PYWEBVIEW_GUI = "qt"; } 

What the non-obvious bits do:

  • LD_LIBRARY_PATH: makes the libs above visible to the pip wheels
  • SSL_CERT_FILE: only needed with nix-shell --pure, otherwise httpx breaks
  • QTWEBENGINE_DISABLE_SANDBOX: the Chromium sandbox doesn't work here, so it's disabled
  • PYWEBVIEW_GUI=qt: forces the Qt backend

Usage

nix-shell uv init uv add "pywebview[qt]" uv run main.py 

main.py

import webview webview.create_window("Hello", "https://example.com") webview.start()