Skip to content

Navigation Menu

Sign in
Sign up

Repository files navigation

ffwebapps

Run any website as a native, chromeless desktop app on Linux β€” built on Firefox's first-party "Web Apps" (Taskbar Tabs) infrastructure, with system-tray integration.

ffwebapps installs websites (PWAs or any site) as standalone apps: their own window with no tabs or address bar, their own taskbar/dock identity, a system-tray icon with an unread badge, close-to-tray / run-in-background, and out-of-scope links that open in your real browser.

It's a CLI-driven fork of PWAsForFirefox's native component, re-architected to drive Firefox's built-in Web Apps support instead of patching the browser chrome at runtime.

Documentation

πŸ“– nine7nine.github.io/ffwebapps β€” architectural and technical reference, with diagrams: the runtime & autoconfig, the IPC protocol and runtime-owned window, the data model, link routing, the tray, the GTK GUI, desktop integration, performance tuning, and packaging. The sources live in docs/ and build with cd docs && ./md2html.sh.

Features

  • Chromeless window β€” no tabs, no address bar; a dark, app-styled titlebar
  • Distinct app identity β€” its own Wayland app_id, so the dock / taskbar / alt-tab treat it as a separate application
  • Single instance β€” each app is a singleton: relaunching it (from the menu, dock, or CLI) focuses the existing window instead of opening a duplicate
  • System tray β€” icon with a live unread badge, run-in-background, close-to-tray (hides/restores at the exact same position and size β€” no minimize animation, no flicker), and Quit to fully stop the app. The tray survives a Plasma restart, and closing never strands a window β€” if no tray is available the X closes the window normally
  • Smart link routing β€” out-of-scope links open in your default browser, while the app's own domains and auth/SSO providers stay in-window
  • Lightweight runtime β€” symlinks your system Firefox (a few hundred KB), so it tracks Firefox updates instead of bundling a second copy
  • Desktop integration β€” generates .desktop launchers and icons for you

Requirements

  • Firefox β‰₯ 151 (provides the Web Apps / Taskbar Tabs modules; used as the linked runtime)
  • Rust / Cargo to build
  • KDE Plasma β€” the tray hide/show and window control currently target KWin (qdbus6)

Install

Arch Linux (PKGBUILD)

cd packages/arch
makepkg -si

From source

cargo build --release --bin ffwebapps --bin ffwebapps-tray
# Put target/release/ffwebapps and ffwebapps-tray on your PATH, and copy
# ./userchrome to /usr/share/ffwebapps/userchrome (or point FFPWA_SYSDATA at it).

Usage

One-time setup (link your system Firefox as the runtime):

ffwebapps runtime install --link

Install an app:

ffwebapps site install <MANIFEST_URL> --document-url <PAGE_URL> --name "App Name"

It then appears in your application menu as a chromeless window with a tray icon.

<MANIFEST_URL> is the site's web-app manifest (the <link rel="manifest" href="..."> on the page); --document-url is the page itself.

Daily use:

  • Launch β€” from your app menu, or ffwebapps site launch <ULID>. If the app is already running, this focuses the existing window (single instance) instead of opening a second one.
  • Close β†’ tray β€” the window's X hides it to the tray; the app keeps running. If the tray isn't available, the X closes the window normally β€” it never gets stuck.
  • Restore β€” single-click the tray icon (toggles hide/show)
  • Quit β€” right-click the tray icon β†’ Quit (fully stops the app)
  • Unread β€” shown as a badge on the tray icon
  • External links β€” open in your default browser automatically

Commands

ffwebapps runtime install [--link] | uninstall | patch
ffwebapps site install <MANIFEST_URL> [--document-url --name --start-url --profile --launch-now --hardware-webrtc --scheduling <spec> ...]
ffwebapps site launch <ULID> [--url <URL> | --protocol [<URL>]]
ffwebapps site update <ULID> [--update-manifest --update-icons --hardware-webrtc <bool> --scheduling <spec>]
ffwebapps site uninstall <ULID>
ffwebapps profile list # lists profiles + their apps and ULIDs
ffwebapps profile create | update <ULID> | remove <ULID>

Run ffwebapps <command> --help for the full flag list.

Configuration

Per-app preferences live in the app's profile (~/.local/share/ffwebapps/profiles/<profile>/):

  • user.js
    • ffwebapps.externalLinks.enabled β€” toggle external-link routing
    • ffwebapps.allowedDomains β€” comma-separated wildcard domains kept in-window
  • chrome/userChrome.css β€” titlebar colour and chrome tweaks (default #000)

Performance (video chat)

For heavy apps like Teams / WhatsApp, two opt-in knobs are exposed (off by default; set them per app at install/update time):

  • --hardware-webrtc β€” force/maximise hardware video decoding for calls. On Linux, Firefox already GPU-decodes regular video and the WebRTC H.264/VP9 paths by default; this writes media.hardware-video-decoding.force-enabled (bypass Firefox's GPU blocklist) and media.navigator.mediadatadecoder_vp8_hardware_enabled (the HW VP8 path used by WhatsApp/Meet). Needs a working VA-API driver; can expose driver bugs, hence opt-in. Verify in about:support (Media β†’ decoder) and about:webrtc during a call (inbound video should use a hardware decoder).

  • --scheduling <spec> β€” run the runtime under a scheduling policy to keep audio/video glitch-free under load. Specs: nice:-5 (gentle, always works), rr:5 / fifo:5 (real-time; need rtprio privileges β€” e.g. membership in a group with rtprio in /etc/security/limits.conf), batch, idle. RT policies gracefully fall back to normal scheduling if they can't be applied.

There is no hardware-audio knob β€” WebRTC audio (Opus) is CPU-cheap and has no GPU path. Echo-cancel / noise-suppression / auto-gain are on by default. The audio win under load is --scheduling (RT), not a pref.

# e.g. Teams with forced HW video decode + real-time scheduling
ffwebapps site update <ULID> --hardware-webrtc true --scheduling rr:5

How it works

ffwebapps drives Firefox's first-party Web Apps (Taskbar Tabs) feature:

  1. The CLI writes a per-app entry into the profile's taskbartabs.json registry plus a small runtime autoconfig (enables the feature and handles external links).
  2. It launches the runtime with firefox -taskbar-tab <id>, which opens a standalone minimal-UI window with a per-app app_id.
  3. userChrome.css strips the remaining toolbar for a chromeless look.
  4. A small ffwebapps-tray helper (a StatusNotifierItem) shows the icon/badge and hides/restores the window via KWin.

No browser-chrome monkeypatching β€” it builds on maintained Mozilla code.

Limitations

  • Tray hide/show and window control target KDE Plasma (KWin); on other desktops the icon appears but hide/restore won't work yet.
  • No drop shadow on the chromeless window (a Wayland CSD limitation).
  • CLI-only: you supply the manifest URL (there is no browser extension for auto-discovery).

Credits & License

A fork of PWAsForFirefox by Filip Ε . Licensed under MPL-2.0 β€” see LICENSE.

About

FFWebapps - Run any website as a native Linux app (Firefox/Gecko-based)

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /