Turn websites into first-class Linux desktop applications with Rust, Tauri, and the system WebView.
Build native-feeling, standalone web app wrappers with CLI-first Linux integration.
Screenshots: KDE Plasma on Arch Linux (alpha MVP workflow).
Two tracks, depending on what you want:
Requirements: any Chromium-based browser installed (chromium, google-chrome, brave, etc.)
mkdir -p ~/.local/bin
curl -L -o ~/.local/bin/deskify \
https://github.com/spalencsar/deskify/releases/latest/download/deskify-linux-x86_64
chmod +x ~/.local/bin/deskify
# If `deskify` is not found, ensure ~/.local/bin is in PATH (common on Ubuntu/Debian):
command -v deskify >/dev/null || { echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc && source ~/.bashrc; }
deskify build --url "https://chat.com" --name "Chat"Follow the full install section below (Tauri/WebKitGTK prerequisites), then:
deskify build --url "https://chat.com" --name "Chat" --backend tauriWeb apps are now core tools, but Linux desktops still treat them like second-class citizens.
- Electron-based wrappers solve distribution, but often at high RAM/disk cost.
- PWAs help in some browsers, but desktop integration is inconsistent across environments.
- The original Nativefier proved the need, but it is now unmaintained.
deskify takes a Linux-first approach: it turns a website into a native-feeling desktop app using Tauri and the system webview (for example webkit2gtk) instead of bundling a full browser engine per app.
Deskify is optimized for Linux users who want native desktop integration and CLI-friendly automation for web apps, without shipping a bundled browser runtime per app.
The comparison below is intentionally rough and practical (not benchmark marketing). It describes tradeoffs, not winners in every category.
| Approach | Runtime model | Desktop integration | Automation / scripting | Isolation / sandbox | Setup complexity | Offline capability |
|---|---|---|---|---|---|---|
| Electron / Nativefier | Bundled Chromium per app | Good | Low to medium | Per-app process, app-bundled runtime | Easy to medium | Depends on the site |
| PWA | Browser runtime | Limited / browser-dependent | Low | Shared browser context | Very easy | Depends on browser + site |
| Flatpak web app models | Sandbox-oriented runtime model | Good | Limited | Strong sandbox model | Medium | Depends on runtime + site |
| Deskify | System WebView | Native (.desktop, icons, WMClass) |
High (CLI-first) | Medium (shared system WebView security model) | Medium (Tauri prerequisites) | Depends on the site |
Deskify focuses on:
- system-native Linux desktop integration
- minimal runtime overhead by relying on the system WebView
- automation-friendly CLI workflows
- straightforward local install/remove lifecycle management
Deskify intentionally does not aim to:
- replace full browser sandbox products
- provide a cross-platform abstraction layer
- ship bundled browser runtimes per generated app
deskify is ready for public use and testing as an early MVP, but it is not production-hardened yet.
- Platform scope: Linux only
- Current architecture: Two supported backends:
- Chromium (default): Uses an existing Chromium-based browser in app mode (fast, no local compilation needed).
- Tauri: Generates and builds a small native wrapper per app using the system WebView.
- Build model: For the Tauri backend,
deskifycompiles the wrapper locally on your machine. - Why this MVP design: Simpler debugging, isolated failures, low contributor complexity.
- Tradeoff: The Tauri backend requires system dependencies and can take significant time to build.
- Test coverage: 43 unit tests covering desktop entry escaping, Tauri config generation, validation, Chromium backend, icon discovery, update option resolution, and app config serialization. Tests are distributed across modules.
- Recent Development: In recent alpha releases, the project has undergone significant internal improvements (new centralized XDG module in
src/xdg.rsand tests moved out ofmain.rs) to increase long-term maintainability.
Deskify currently supports two backends:
flowchart TD
A[deskify CLI] --> B{Backend?}
B -->|Tauri| C[Generate + build Tauri wrapper]
B -->|Chromium| D[Use installed Chromium browser in app mode]
C --> E[Install .desktop + icon]
D --> E
E --> F[Launch from Linux app menu]
The Chromium backend (default) uses an existing Chromium-based browser in app mode and skips the local build entirely.
The Tauri backend generates and compiles a small native wrapper per app using the system WebView (requires Tauri build dependencies).
- The Tauri backend requires Linux system dependencies (WebKitGTK etc.) and can take significant time to build.
- Generated app build success with the Tauri backend can vary by distro/system setup.
- Some modern sites may not work well in the system WebView (Tauri backend).
- The Chromium backend requires a Chromium-based browser installed (Flatpak browsers are not supported).
- No official cross-platform support (Windows/macOS) yet.
- GitHub Releases / binary automation for
deskifyitself may lag behind source updates during early MVP.
Deskify aims to make web applications first-class Linux desktop applications.
Planned evolution (direction, not promise):
- Shared runtime model for multiple apps
- Per-app config and icon installs without full rebuilds
- Stronger Linux desktop integration (deployment, automation, kiosk/admin workflows)
- Better distro compatibility guidance and troubleshooting
The current per-app build approach is intentional for the MVP. The goal is to keep it simple now while making the longer-term direction visible.
flowchart TD
A[deskify CLI] --> B[deskify runtime binary]
A --> C[App config files]
A --> D[Icons + .desktop entries]
C --> E[apps/chatgpt.json]
C --> F[apps/home-assistant.json]
B --> G[Load app config at launch]
G --> H[Open site in system webview]
D --> I[Linux app menu integration]
The table above covers the technical tradeoffs in more detail. In practice, deskify is most useful when you want:
- a CLI-first workflow for repeatable installs and automation
- Linux-native desktop integration (
.desktop, icons, window class behavior) - a system-WebView-based runtime model instead of shipping a bundled browser per app
- System-WebView Runtime Model: Generated wrappers stay small because Deskify relies on the system WebView instead of bundling a browser runtime per app.
- Automatic Icon Fetching: Scrapes high-quality 128x128 favicons automatically using the Google Favicon API.
- Layered Icon Fallbacks: Tries site-provided icons first (
<link rel="icon">,/favicon.ico), then falls back to the Google Favicon API, then a dummy icon. - XDG-Compliant System Integration: Safely creates
.desktopentries in~/.local/share/applicationsand manages application icons in~/.local/share/icons/hicolor/. - Wayland/X11 Ready: Perfectly binds
StartupWMClassto ensure your DE groups the app exactly to its custom icon (no generic gear icons in GNOME/KDE taskbars). - Kiosk / Fullscreen Mode: Pin applications perfectly as dashboards.
- User-Agent Spoofing: Trick picky sites (like WhatsApp Web) into working within the webview.
- Clean App Management: Effortlessly list and remove created apps without leaving orphaned files behind.
Deskify provides Linux release binaries. Download the latest release and install it into ~/.local/bin:
mkdir -p ~/.local/bin
curl -L -o ~/.local/bin/deskify \
https://github.com/spalencsar/deskify/releases/latest/download/deskify-linux-x86_64
chmod +x ~/.local/bin/deskify
deskify --helpNotes:
- The
tauribackend still requires Tauri/WebKitGTK system dependencies to build wrappers locally. - The
chromiumbackend does not require Tauri prerequisites (but it requires an installed Chromium-based browser).
An AUR package is available (prebuilt binary package):
yay -S deskify-binv0.1.0-alpha.N). Expect occasional breaking changes during early development.
Because deskify compiles Tauri applications natively on your machine, you need the standard Tauri prerequisites installed before using it.
On Ubuntu / Debian:
sudo apt update
sudo apt install libwebkit2gtk-4.1-dev \
build-essential \
curl \
wget \
file \
libssl-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-devOn Arch Linux / Manjaro:
sudo pacman -S webkit2gtk-4.1 \
base-devel \
curl \
wget \
file \
openssl \
appmenu-gtk-module \
gtk3 \
libappindicator-gtk3 \
librsvg \
libvips(For Fedora or other distros, refer to the Tauri Prerequisites Guide.)
You'll need the Rust compiler and the Tauri CLI to compile the generated apps.
# Ensure Rust is installed
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install Tauri-CLI globally
cargo install tauri-cli --version "^2.0.0"Clone the repository and install it directly via Cargo:
git clone https://github.com/spalencsar/deskify.git
cd deskify
cargo install --path .The build subcommand requires a --url and a --name.
deskify build --url "https://chatgpt.com" --name "ChatGPT"Once the build finishes, ChatGPT will instantly appear in your system Application Launcher (e.g., Rofi, Wofi, GNOME Dash).
deskify derives a safe internal ID from the app name (for example, ChatGPT becomes chatgpt).
Deskify supports two backend modes:
chromium(default): Uses an already installed Chromium-based browser (chromium,google-chrome,brave, etc.) in app mode. Better site compatibility and no local Tauri build, but depends on a browser installed on the system.tauri: Uses the system WebView (webkit2gtkon Linux). Produces small wrappers and strong Linux desktop integration, but requires a Tauri build environment and some sites may fail due to engine compatibility.
If you specifically want the system WebView backend, use --backend tauri.
Quick decision rule:
- Start with the default
chromiumbackend for the fastest install path and broad site compatibility. - Use
--backend tauriwhen you specifically want a system-WebView wrapper and have the Tauri/WebKitGTK prerequisites installed.
deskify build \
--url "https://example.com/dashboard" \
--name "Dashboard" \
--fullscreen \
--user-agent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36" \
--dark-mode \
--width 1280 \
--height 720Frameless example (without fullscreen):
deskify build \
--url "https://chat.com" \
--name "Chat" \
--no-decorations \
--width 1200 \
--height 800Preview the generated backend config without building/installing:
deskify build --url "https://chat.com" --name "Chat" --print-configChromium compatibility mode (no local Tauri build):
deskify build --url "https://mail.proton.me" --name "Proton Mail" --backend chromiumChromium with shared browser profile (uses existing browser profile/session model):
deskify build \
--url "https://app.slack.com" \
--name "Slack" \
--backend chromium \
--profile-scope sharedChromium with explicit browser binary:
deskify build \
--url "https://github.com" \
--name "GitHub" \
--backend chromium \
--browser-bin /usr/bin/brave-browserPreview planned actions only (dry run):
deskify build --url "https://chat.com" --name "Chat" --dry-run--icon <PATH>: Provide a custom PNG icon instead of auto-downloading one.--fullscreen: Starts the app in Kiosk mode.--no-decorations: Disables native window decorations (frameless window; useful for dashboards/kiosk setups).--user-agent <UA>: Useful to bypass webview restrictions on certain platforms.--dark-mode: Requests a dark theme (tauri) or Chromium dark mode (chromium).--width <PX>/--height <PX>: Sets the startup resolution.--backend <tauri|chromium>: Choose system WebView (tauri) or Chromium app mode (chromium).--browser-bin <PATH>: Use a specific Chromium-based browser binary (Chromium backend only).--profile-scope <isolated|shared>: Chromium backend profile behavior (isolatedcreates a per-app profile under~/.local/share/deskify/profiles/).--print-config: Prints the generated backend config and exits.--dry-run: Shows planned actions without building/installing.
Note for Chromium backend:
--no-decorationsis best-effort and may be ignored by the browser/window manager.--widthand--heightare applied together (--window-size) only when both are provided.- Deskify auto-detects a Chromium-based browser from
PATH, but some distros ship Chromium-based browser commands (Chrome/Chromium/Brave, etc.) as wrapper scripts or use different binary names/paths (for example on BigLinux). If launches fail, set--browser-binto a real browser binary. - Flatpak-installed browsers are not supported out of the box (they usually require
flatpak run ...). Use a native browser binary for now; Flatpak support may be added in a future release.
Troubleshooting (find the real browser binary):
command -v chrome chromium google-chrome google-chrome-stable brave-browser 2>/dev/null
ls -la /usr/bin/chrome /usr/bin/chromium /usr/bin/google-chrome /usr/bin/google-chrome-stable 2>/dev/nullYou can view all applications generated by deskify:
deskify listVerbose list (includes URL/backend when metadata is available):
deskify list --verboseOutput:
Installed Deskify Apps:
- ChatGPT (Internal ID: chatgpt, Backend: tauri)
- Proton Mail (Internal ID: proton-mail, Backend: chromium)
To entirely uninstall an app (including the binary, desktop entry, and icons):
deskify remove chatgptremove expects this internal ID (sanitized lowercase letters, numbers, -), not the display name.
Rebuild and reinstall an existing app ID without manually running remove + build:
deskify update chat --url "https://chat.com" --name "Chat" --no-decorationsDeskify persists app metadata under ~/.local/share/deskify/apps/<id>.json. With persisted metadata, update can be used without --url.
If an older app has no metadata yet, provide --url once (or rebuild once) to migrate it.
update <id> keeps the existing internal ID stable even if you change the display name.
Boolean options from saved metadata can be turned off explicitly:
deskify update chat --no-fullscreen --decorations --light-modeYou can also preview an update:
deskify update chat --url "https://chat.com" --dry-run
deskify update chat --url "https://chat.com" --print-configSwitch an existing app to Chromium compatibility mode while keeping the same internal ID:
deskify update chat --url "https://chat.com" --name "Chat" --backend chromiumCheck local prerequisites and common environment issues (Rust/Cargo, cargo tauri, pkg-config, directories):
deskify doctordoctor also checks whether a Chromium-based browser is available in PATH for --backend chromium.
deskify build --url "https://example.com" --name "Example"
deskify list
deskify remove exampleAlso test invalid IDs:
deskify remove ../foo
deskify remove FooBarExpected: clean validation error and no unintended file deletion.
- Recommended tag format during MVP:
v0.1.0-alpha.N - GitHub Releases publish a Linux
deskifyCLI binary on tags (v*)
For the latest alpha, see GitHub Releases (and continue with v0.1.0-alpha.N for follow-up releases).
deskify is built on the shoulders of giants. It leverages the following fantastic open-source projects:
- Tauri - The core framework driving the native wrap.
- Clap - Command-Line Argument Parser for Rust.
- Anyhow - Excellent error handling context.
- Ureq - Minimalist sync HTTP request library (used for icon fetching).
- Directories - Abstractions for standard OS directories (XDG Base Dirs).
This project is licensed under the MIT License.


