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 withnix-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()
Top comments (0)