A Linux desktop app that wraps any web URL in a persistent WebKitGTK webview to create standalone PWA-style apps with desktop integration, URL filtering, and install/uninstall support.
  • Rust 98.8%
  • Shell 0.8%
  • Dockerfile 0.4%
Find a file
Vlad Verestiuc 18ab7ef204
Some checks failed
CI / arch-image (push) Successful in 4s
CI / ci-image (push) Successful in 6s
CI / build (push) Successful in 23s
CI / test (push) Successful in 45s
CI / dist-artifacts (push) Successful in 11s
CI / arch-package (push) Successful in 28s
CI / release (push) Failing after 10s
Use tag version for Arch package builds
2026-02-09 16:56:19 +02:00
.forgejo/workflows Update release job to reuse tag release 2026-02-09 15:47:35 +02:00
ci CI: add python to Arch image and document deps bundling 2026-02-08 13:02:47 +02:00
misc/pwaizer-git Use tag version for Arch package builds 2026-02-09 16:56:19 +02:00
src Forward disallowed URLs to external browser 2026-02-09 15:38:22 +02:00
tests Refine settings validation and stabilize env tests 2026-02-09 12:15:22 +02:00
.gitignore Initial commit: pwaizer desktop webview wrapper 2026-02-08 03:33:11 +02:00
AGENTS.md Forward disallowed URLs to external browser 2026-02-09 15:38:22 +02:00
build.rs Initial commit: pwaizer desktop webview wrapper 2026-02-08 03:33:11 +02:00
Cargo.lock Refactor config/manifest storage and module layout 2026-02-09 01:46:30 +02:00
Cargo.toml Refactor config/manifest storage and module layout 2026-02-09 01:46:30 +02:00
INSTRUCTIONS.md Forward disallowed URLs to external browser 2026-02-09 15:38:22 +02:00
LICENSE Fix edge cases, add README and LICENSE 2026-02-08 03:35:39 +02:00
README.md Refactor config/manifest storage and module layout 2026-02-09 01:46:30 +02:00

Pwaizer

A Linux desktop application that wraps any web URL in a persistent WebKitGTK webview, turning websites into standalone PWA-style apps.

Features

  • Singleton process — launching a second instance activates the existing window via D-Bus (GTK application ID).
  • Persistent state — cookies, localStorage, and IndexedDB survive across restarts. Data is stored per-host under $XDG_DATA_HOME/pwaizer/<host>.
  • Window hiding — ESC or the close button hides the window; the webview keeps running in the background.
  • URL filtering--allow-url patterns control which navigations stay in-app and which open in the default browser.
  • Desktop integration — the install subcommand generates a .desktop file, downloads PWA and page icons (with favicon fallback), and optionally creates a systemd user service for auto-start at login.
  • Clean uninstall — the uninstall subcommand removes the .desktop file, icons, and systemd service.

Requirements

  • Linux with GTK 3 and WebKitGTK 4.1
  • Rust (latest stable)

On Arch Linux:

sudo pacman -S webkit2gtk-4.1 gtk3

On Debian/Ubuntu:

sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev

Building

cargo build --release

The binary is at target/release/pwaizer.

Usage

Launch a webview for a URL:

pwaizer --app-url https://example.com

With all options:

pwaizer \
  --app-url https://app.example.com \
  --title "Example App" \
  --app-id app.example.com \
  --keep-in-background \
  --start-minimized \
  --hide-on-blur \
  --window-size 1400x900 \
  --allow-url 'https://app.example.com/*' \
  --allow-url 'https://auth.example.com/*' \
  --allow-url 'https://cdn.example.com/*'

Install as a desktop app

pwaizer install \
  --app-url https://app.example.com \
  --allow-url 'https://app.example.com/*' \
  --allow-url 'https://auth.example.com/*' \
  --allow-url 'https://cdn.example.com/*' \
  --keep-in-background \
  --hide-on-blur \
  --run-at-startup

This creates:

  • ~/.local/share/applications/pwaizer-app.example.com.desktop
  • Icons under ~/.local/share/icons/hicolor/
  • A systemd user service (if --run-at-startup is used)
  • A config file under ~/.config/pwaizer/

Uninstall

pwaizer uninstall --app-url https://app.example.com

Only --app-url is accepted for uninstall.

Configuration

The install step writes a config file at:

$XDG_CONFIG_HOME/pwaizer/<host>.yaml (or ~/.config/pwaizer/<host>.yaml).

On startup, if the config file exists its values are used. Any CLI flags passed at runtime override the config values. The desktop file and systemd service pass only --app-url; all other flags come from the config file.

If no --allow-url patterns are provided, Pwaizer allows the app URL host and subdomains by default: <scheme>://<host>/* and <scheme>://*.<host>/*.

Example config:

keep_in_background: true
start_minimized: false
hide_on_blur: true
app_url: 'https://app.example.com'
app_id: 'app.example.com'
window_size: '1400x900'
allow_urls:
  - 'https://app.example.com/*'
  - 'https://auth.example.com/*'
manifest:
  name: 'Example App'
  start_url: 'https://app.example.com'
  scope: 'https://app.example.com/'

CLI Reference

Flag Description
--app-url <URL> URL to load (required)
--title <TITLE> Window title (defaults to page <title>)
--app-id <ID> GTK application ID (defaults to URL host)
--keep-in-background Hide instead of exit on close/ESC
--start-minimized Start with window hidden
--hide-on-blur Hide the window when it loses focus
--window-size <WxH> Window dimensions, e.g. 1400x900 (default: 1200x800)
--allow-url <PATTERN> URL pattern for in-app navigation (repeatable, supports * wildcards)

Subcommands

Subcommand Description
(none) Launch the webview
install Create .desktop file, download icons, optionally enable systemd service
uninstall Remove .desktop file, icons, and systemd service

The install subcommand accepts an additional --run-at-startup flag.

AUR Package

An AUR -git package is available in misc/pwaizer-git/. To build:

cd misc/pwaizer-git
makepkg -si

CI Image

CI uses a prebuilt container image to avoid reinstalling system packages on every run. The image is rebuilt only when ci/Dockerfile or ci/apt-packages.txt changes, and is tagged with rust-1.93-<hash6>.

Required CI variables:

  • DOCKER_REGISTRY_USER (variable)
  • DOCKER_REGISTRY_PASSWORD (secret)

The image is pushed to the project container registry and used by the build and test jobs.

Arch CI Image

The Arch package build uses a prebuilt Arch Linux image to cache makepkg dependencies. It rebuilds only when ci/arch.Dockerfile or ci/arch-packages.txt changes, and uses a tag arch-rolling-<hash6>.

The image is pushed to the project container registry and used by the arch-package job. It also bundles PKGBUILD depends and makedepends into the image build to reduce dependency installs during CI.

License

MIT