diff --git a/fluxer_desktop/packaging/arch/PKGBUILD b/fluxer_desktop/packaging/arch/PKGBUILD
new file mode 100644
index 000000000..fd5b54d86
--- /dev/null
+++ b/fluxer_desktop/packaging/arch/PKGBUILD
@@ -0,0 +1,106 @@
+# SPDX-License-Identifier: AGPL-3.0-or-later
+_channel="${FLUXER_CHANNEL:-stable}"
+if [[ $_channel == canary ]]; then
+ pkgname=fluxer-canary
+ _appname='Fluxer Canary'
+ _comment='Canary build of Fluxer'
+else
+ pkgname=fluxer
+ _appname='Fluxer'
+ _comment='Instant messaging and VoIP'
+fi
+pkgver="${FLUXER_VERSION:?FLUXER_VERSION must be set}"
+pkgrel=1
+pkgdesc='Instant messaging and VoIP application'
+arch=('x86_64' 'aarch64')
+url='https://fluxer.app'
+license=('AGPL-3.0-or-later')
+depends=(
+ 'alsa-lib'
+ 'at-spi2-core'
+ 'cairo'
+ 'dbus'
+ 'expat'
+ 'glib2'
+ 'glibc'
+ 'gtk3'
+ 'libcups'
+ 'libgcc'
+ 'libnotify'
+ 'libpipewire'
+ 'libpulse'
+ 'libsecret'
+ 'libstdc++'
+ 'libx11'
+ 'libxcb'
+ 'libxcomposite'
+ 'libxdamage'
+ 'libxext'
+ 'libxfixes'
+ 'libxkbcommon'
+ 'libxrandr'
+ 'mesa'
+ 'nspr'
+ 'nss'
+ 'pango'
+ 'systemd-libs'
+ 'xdg-utils'
+)
+optdepends=(
+ 'libdbusmenu-glib: tray icon menu support'
+ 'libspeechd: text to speech support'
+ 'xdg-desktop-portal: screen sharing and file dialogs on Wayland'
+)
+provides=("$pkgname-bin")
+conflicts=("$pkgname-bin")
+replaces=("$pkgname-bin")
+options=('!strip' '!debug' 'emptydirs')
+source=("$pkgname-$pkgver-$CARCH.tar.gz")
+sha256sums=('SKIP')
+
+package() {
+ local payload opt size
+ payload=$(printf '%s\n' "$srcdir"/*-linux-*/ | head -n1)
+ opt="$pkgdir/opt/$pkgname"
+
+ install -dm755 "$opt"
+ cp -a "$payload"/. "$opt/"
+ chmod 4755 "$opt/chrome-sandbox"
+
+ install -dm755 "$pkgdir/usr/bin"
+ ln -s "/opt/$pkgname/$pkgname" "$pkgdir/usr/bin/$pkgname"
+
+ install -dm755 "$pkgdir/usr/share/applications"
+ cat > "$pkgdir/usr/share/applications/$pkgname.desktop" <<-EOF
+ [Desktop Entry]
+ Name=$_appname
+ Exec=/opt/$pkgname/$pkgname %U
+ Terminal=false
+ Type=Application
+ Icon=$pkgname
+ StartupWMClass=$pkgname
+ GenericName=Instant Messenger
+ Comment=$_comment
+ Keywords=chat;im;messaging;messenger;voip;voice;video;call;
+ Categories=Network;InstantMessaging;Chat;
+ StartupNotify=true
+ SingleMainWindow=true
+ MimeType=x-scheme-handler/fluxer;
+ X-GNOME-UsesNotifications=true
+ Actions=open-settings;new-dm;
+
+ [Desktop Action open-settings]
+ Name=Open Settings
+ Exec=/opt/$pkgname/$pkgname --fluxer-task=open-settings %U
+
+ [Desktop Action new-dm]
+ Name=New Direct Message
+ Exec=/opt/$pkgname/$pkgname --fluxer-task=new-dm %U
+ EOF
+ chmod 644 "$pkgdir/usr/share/applications/$pkgname.desktop"
+
+ for size in 16 24 32 48 64 128 256 512; do
+ install -Dm644 "$opt/resources/icons/${size}x${size}.png" \
+ "$pkgdir/usr/share/icons/hicolor/${size}x${size}/apps/$pkgname.png"
+ done
+}
diff --git a/fluxer_desktop/packaging/linux/app.fluxer.Fluxer.metainfo.xml b/fluxer_desktop/packaging/linux/app.fluxer.Fluxer.metainfo.xml
index 2cad859fb..4a6182bd7 100644
--- a/fluxer_desktop/packaging/linux/app.fluxer.Fluxer.metainfo.xml
+++ b/fluxer_desktop/packaging/linux/app.fluxer.Fluxer.metainfo.xml
@@ -47,9 +47,6 @@
https://fluxerstatic.com/marketing/screenshots/desktop-1920w.avif
-
-
-
https://github.com/fluxerapp/fluxer/issues
https://fluxer.app
https://fluxer.app/donate
diff --git a/fluxer_desktop/packaging/linux/app.fluxer.Fluxer.sh b/fluxer_desktop/packaging/linux/app.fluxer.Fluxer.sh
new file mode 100755
index 000000000..fabba85a4
--- /dev/null
+++ b/fluxer_desktop/packaging/linux/app.fluxer.Fluxer.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+export TMPDIR="${XDG_RUNTIME_DIR}/app/${FLATPAK_ID}"
+export FLUXER_FLATPAK_COMMAND="${FLATPAK_ID}"
+
+exec zypak-wrapper "/app/fluxer/fluxer" "$@"
diff --git a/fluxer_desktop/packaging/linux/app.fluxer.Fluxer.yml b/fluxer_desktop/packaging/linux/app.fluxer.Fluxer.yml
new file mode 100644
index 000000000..2633b2339
--- /dev/null
+++ b/fluxer_desktop/packaging/linux/app.fluxer.Fluxer.yml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: AGPL-3.0-or-later
+id: app.fluxer.Fluxer
+runtime: org.freedesktop.Platform
+runtime-version: '25.08'
+sdk: org.freedesktop.Sdk
+base: org.electronjs.Electron2.BaseApp
+base-version: '25.08'
+branch: stable
+command: app.fluxer.Fluxer
+separate-locales: false
+finish-args:
+ - --share=ipc
+ - --share=network
+ - --socket=wayland
+ - --socket=fallback-x11
+ - --socket=pulseaudio
+ - --device=all
+ - --filesystem=xdg-download
+ - --filesystem=xdg-run/pipewire-0:ro
+ - --filesystem=xdg-run/speech-dispatcher:ro
+ - --talk-name=org.freedesktop.Notifications
+ - --talk-name=org.kde.StatusNotifierWatcher
+ - --talk-name=org.ayatana.indicator.application
+ - --talk-name=com.canonical.indicator.application
+ - --env=ELECTRON_OZONE_PLATFORM_HINT=auto
+ - --env=XCURSOR_PATH=/run/host/user-share/icons:/run/host/share/icons
+build-options:
+ strip: false
+ no-debuginfo: true
+cleanup-commands:
+ - rm -f /app/fluxer/chrome-sandbox
+modules:
+ - name: fluxer
+ buildsystem: simple
+ build-commands:
+ - install -Dm755 app.fluxer.Fluxer.sh ${FLATPAK_DEST}/bin/${FLATPAK_ID}
+ - mkdir -p ${FLATPAK_DEST}/fluxer
+ - cp -a app/. ${FLATPAK_DEST}/fluxer/
+ - patch-electron-desktop-filename ${FLATPAK_DEST}/fluxer/resources/app.asar
+ - install -Dm644 app.fluxer.Fluxer.desktop ${FLATPAK_DEST}/share/applications/${FLATPAK_ID}.desktop
+ - install -Dm644 app.fluxer.Fluxer.metainfo.xml ${FLATPAK_DEST}/share/metainfo/${FLATPAK_ID}.metainfo.xml
+ - install -Dm644 app.fluxer.Fluxer.svg ${FLATPAK_DEST}/share/icons/hicolor/scalable/apps/${FLATPAK_ID}.svg
+ sources:
+ - type: file
+ path: app.fluxer.Fluxer.sh
+ - type: file
+ path: app.fluxer.Fluxer.desktop
+ - type: file
+ path: app.fluxer.Fluxer.metainfo.xml
+ - type: file
+ path: app.fluxer.Fluxer.svg
diff --git a/fluxer_desktop/packaging/linux/app.fluxer.FluxerCanary.sh b/fluxer_desktop/packaging/linux/app.fluxer.FluxerCanary.sh
new file mode 100755
index 000000000..115588235
--- /dev/null
+++ b/fluxer_desktop/packaging/linux/app.fluxer.FluxerCanary.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+export TMPDIR="${XDG_RUNTIME_DIR}/app/${FLATPAK_ID}"
+export FLUXER_FLATPAK_COMMAND="${FLATPAK_ID}"
+
+exec zypak-wrapper "/app/fluxer/fluxer-canary" "$@"
diff --git a/fluxer_desktop/packaging/linux/app.fluxer.FluxerCanary.yml b/fluxer_desktop/packaging/linux/app.fluxer.FluxerCanary.yml
new file mode 100644
index 000000000..603561f28
--- /dev/null
+++ b/fluxer_desktop/packaging/linux/app.fluxer.FluxerCanary.yml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: AGPL-3.0-or-later
+id: app.fluxer.FluxerCanary
+runtime: org.freedesktop.Platform
+runtime-version: '25.08'
+sdk: org.freedesktop.Sdk
+base: org.electronjs.Electron2.BaseApp
+base-version: '25.08'
+branch: stable
+command: app.fluxer.FluxerCanary
+separate-locales: false
+finish-args:
+ - --share=ipc
+ - --share=network
+ - --socket=wayland
+ - --socket=fallback-x11
+ - --socket=pulseaudio
+ - --device=all
+ - --filesystem=xdg-download
+ - --filesystem=xdg-run/pipewire-0:ro
+ - --filesystem=xdg-run/speech-dispatcher:ro
+ - --talk-name=org.freedesktop.Notifications
+ - --talk-name=org.kde.StatusNotifierWatcher
+ - --talk-name=org.ayatana.indicator.application
+ - --talk-name=com.canonical.indicator.application
+ - --env=ELECTRON_OZONE_PLATFORM_HINT=auto
+ - --env=XCURSOR_PATH=/run/host/user-share/icons:/run/host/share/icons
+build-options:
+ strip: false
+ no-debuginfo: true
+cleanup-commands:
+ - rm -f /app/fluxer/chrome-sandbox
+modules:
+ - name: fluxer
+ buildsystem: simple
+ build-commands:
+ - install -Dm755 app.fluxer.FluxerCanary.sh ${FLATPAK_DEST}/bin/${FLATPAK_ID}
+ - mkdir -p ${FLATPAK_DEST}/fluxer
+ - cp -a app/. ${FLATPAK_DEST}/fluxer/
+ - patch-electron-desktop-filename ${FLATPAK_DEST}/fluxer/resources/app.asar
+ - install -Dm644 app.fluxer.FluxerCanary.desktop ${FLATPAK_DEST}/share/applications/${FLATPAK_ID}.desktop
+ - install -Dm644 app.fluxer.FluxerCanary.metainfo.xml ${FLATPAK_DEST}/share/metainfo/${FLATPAK_ID}.metainfo.xml
+ - install -Dm644 app.fluxer.FluxerCanary.svg ${FLATPAK_DEST}/share/icons/hicolor/scalable/apps/${FLATPAK_ID}.svg
+ sources:
+ - type: file
+ path: app.fluxer.FluxerCanary.sh
+ - type: file
+ path: app.fluxer.FluxerCanary.desktop
+ - type: file
+ path: app.fluxer.FluxerCanary.metainfo.xml
+ - type: file
+ path: app.fluxer.FluxerCanary.svg
diff --git a/fluxer_desktop/packaging/linux/build-flatpak.sh b/fluxer_desktop/packaging/linux/build-flatpak.sh
new file mode 100755
index 000000000..d5a10431b
--- /dev/null
+++ b/fluxer_desktop/packaging/linux/build-flatpak.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+# SPDX-License-Identifier: AGPL-3.0-or-later
+set -eu
+
+: "${FLATPAK_APP_ID:?FLATPAK_APP_ID must be set}"
+: "${FLATPAK_TARGET_ARCH:?FLATPAK_TARGET_ARCH must be set}"
+: "${FLATPAK_RUNTIME_BRANCH:?FLATPAK_RUNTIME_BRANCH must be set}"
+: "${HOST_UID:?HOST_UID must be set}"
+: "${HOST_GID:?HOST_GID must be set}"
+
+dnf install -y --setopt=install_weak_deps=False flatpak flatpak-builder
+
+flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
+flatpak install -y --noninteractive --arch="${FLATPAK_TARGET_ARCH}" flathub \
+ "org.freedesktop.Platform//${FLATPAK_RUNTIME_BRANCH}" \
+ "org.freedesktop.Sdk//${FLATPAK_RUNTIME_BRANCH}" \
+ "org.electronjs.Electron2.BaseApp//${FLATPAK_RUNTIME_BRANCH}"
+
+cd /build
+rm -rf repo builddir .fb-state
+
+flatpak-builder \
+ --arch="${FLATPAK_TARGET_ARCH}" \
+ --repo=repo \
+ --force-clean \
+ --disable-rofiles-fuse \
+ --state-dir=.fb-state \
+ builddir "${FLATPAK_APP_ID}.yml"
+
+rm -rf builddir .fb-state
+ostree --repo=repo refs
+rm -rf repo/tmp repo/state repo/extensions repo/.lock
+chown -R "${HOST_UID}:${HOST_GID}" repo