1. Install required tools and base flatpak packages

apt install flatpak flatpak-builder pipx appstream unzip 

from flatpak we are going to install latest node extension and gnome (sdk & platform)

flatpak install org.freedesktop.Sdk.Extension.node26 flatpak install org.gnome.Sdk//51 flatpak install org.gnome.Platform//51 

pip and node generator

wget https://raw.githubusercontent.com/flatpak/flatpak-builder-tools/master/pip/flatpak-pip-generator.py wget https://github.com/flatpak/flatpak-builder-tools/archive/refs/heads/master.zip unzip master.zip "flatpak-builder-tools-master/node/*" pipx install ./flatpak-builder-tools-master/node/ 

Verify python exists and version in gnome Sdk

flatpak run --command=python3 org.gnome.Sdk//51 --version 

2. Package Files

In packaging/flatpak dir in the root add .desktop, .xml, .svg, .yml files

io.github.viraj_sh.uniclare_client.desktop

[Desktop Entry] Name=Uniclare Client Exec=unidesk Icon=io.github.viraj_sh.uniclare_client Terminal=false Type=Application Categories=Utility; StartupWMClass=unidesk 

io.github.viraj_sh.uniclare_client.metainfo.xml

<?xml version="1.0" encoding="UTF-8"?> <component type="desktop-application"> <id>io.github.viraj_sh.uniclare_client</id> <name>Uniclare Client</name> <summary>View data that is hidden on the Uniclare App or Student Portal</summary> <metadata_license>MIT</metadata_license> <project_license>MIT</project_license> <description> <p>Uniclare Client lets you view data that is hidden on the Uniclare App or Student Portal.</p> </description> <launchable type="desktop-id">io.github.viraj_sh.uniclare_client.desktop</launchable> <developer id="io.github.viraj_sh"> <name>viraj-sh</name> </developer> <url type="homepage">https://github.com/viraj-sh/uniclare-client</url> <content_rating type="oars-1.1"/> <releases> <release version="3.0.0" date="2026-10-25"/> </releases> </component> 

io.github.viraj_sh.uniclare_client.yml

id: io.github.viraj_sh.uniclare_client runtime: org.gnome.Platform runtime-version: '51' sdk: org.gnome.Sdk sdk-extensions: - org.freedesktop.Sdk.Extension.node26 command: unidesk finish-args: - --share=network - --share=ipc - --socket=wayland - --socket=fallback-x11 - --socket=system-bus - --device=dri - --env=PYWEBVIEW_GUI=gtk - --env=SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt modules: - python3-deps.json - python3-uv-build.json - name: uniclare-client buildsystem: simple build-options: append-path: /usr/lib/sdk/node26/bin strip: true build-commands: - cd web && npm ci --offline --cache=$FLATPAK_BUILDER_BUILDDIR/flatpak-node/npm-cache && npm run build - pip3 install --prefix=/app --no-deps --no-build-isolation . - install -Dm644 packaging/flatpak/io.github.viraj_sh.uniclare_client.desktop /app/share/applications/io.github.viraj_sh.uniclare_client.desktop - install -Dm644 packaging/flatpak/io.github.viraj_sh.uniclare_client.metainfo.xml /app/share/metainfo/io.github.viraj_sh.uniclare_client.metainfo.xml - install -Dm644 packaging/flatpak/io.github.viraj_sh.uniclare_client.svg /app/share/icons/hicolor/scalable/apps/io.github.viraj_sh.uniclare_client.svg sources: - type: dir path: ../.. - generated-sources.json 

Validate .xml file

appstreamcli validate --pedantic packaging/flatpak/io.github.viraj_sh.uniclare_client.metainfo.xml 

3. Dependences

Generate requirements.txt and remove pyqt or gnome related libraries since we are using flatpak gnome base package for the same

uv pip compile pyproject.toml --extra desktop -o requirements.txt 
grep -viE '^(pyqt6|qtpy|pygobject|pycairo)' requirements.txt > requirements.clean.txt && mv requirements.clean.txt requirements.txt 

Run this to generate python3-deps.json

export SSL_CERT_FILE=$(python3 -m certifi) # optional nixos python3 flatpak-pip-generator.py \ --runtime='org.gnome.Sdk//51' \ --prefer-wheels=pydantic-core \ --requirements-file=requirements.txt \ --output ./packaging/flatpak/python3-deps 

Run this to generate python3-uv-build.json

uv pip install pip python -m pip download "uv_build>=0.11.21,<0.12.0" --only-binary=:all: --no-deps -d /tmp/uvb ls /tmp/uvb # confirm a .whl is present echo "uv_build==0.11.33" > uvb.txt python3 flatpak-pip-generator.py \ --runtime='org.gnome.Sdk//51' \ --prefer-wheels=uv_build \ --requirements-file=uvb.txt \ --output ./packaging/flatpak/python3-uv-build 

Run this to generate generated-sources.json

flatpak-node-generator npm web/package-lock.json -o generated-sources.json 

4. Build & Test Locally

To build run this command

flatpak-builder --user --force-clean --install-deps-from=flathub --disable-rofiles-fuse build-dir ./packaging/flatpak/io.github.viraj_sh.uniclare_client.yml 

To install run this command

flatpak-builder --user --force-clean --install-deps-from=flathub --install --repo=repo build-dir ./packaging/flatpak/io.github.viraj_sh.uniclare_client.yml 

To RUN the app run this command

flatpak run io.github.viraj_sh.uniclare_client 

5. Create a Bundle

To create a bundle run this command

flatpak build-bundle ./packaging/flatpak/repo uniclare-client.flatpak io.github.viraj_sh.uniclare_client 

Check the bundle size

ls -lh uniclare-client.flatpak 

Clean UP

To uninstall the app

flatpak uninstall --user -y io.github.viraj_sh.uniclare_client || true 

To cleanup flatpak packages

flatpak uninstall --user --unused -y || true 

Remove build dir and cache

rm -rf ./packaging/flatpak/build-dir ./packaging/flatpak/repo 

Remove apps persisted data

rm -rf ~/.var/app/io.github.viraj_sh.uniclare_client 

Remove flatpak builder cache

rm -rf .flatpak-builder