| name | flatpak-builder |
| description | Complete guide for packaging Linux applications as Flatpaks for distribution on Flathub. Use this skill whenever the user mentions: "flatpak", "flathub", "packaging for linux", "creating a flatpak", "flatpak manifest", "flatpak sandbox", "desktop file", "metainfo", "appstream", "flatpak-builder", "linux app distribution", "app icon linux", ".desktop file", "publish to flathub", or any time they want to make their app installable via flatpak. ALWAYS trigger on any flatpak/flathub packaging question, even if they just say "how do I make my app a flatpak" or "I want to publish my app on Linux". Covers manifests, runtimes, MetaInfo/AppStream XML, desktop files, icons at all sizes, sandbox permissions, build systems (cmake, meson, simple), Flathub submission, linting, GitHub Actions CI, and verification. |
Flatpak Builder Skill
This skill covers everything needed to package an application as a Flatpak and
publish it to Flathub — from the first manifest to a live store listing.
Quick Reference — Required Files
Every Flathub submission needs these files:
| File | Location (in build) | Purpose |
|---|
$APP_ID.yaml (or .json) | repo root | Flatpak manifest |
$APP_ID.metainfo.xml | /app/share/metainfo/ | AppStream metadata |
$APP_ID.desktop | /app/share/applications/ | Desktop entry |
| Icons (multiple sizes) | /app/share/icons/hicolor/<size>/apps/ | App icons |
→ For manifest deep-dive, see references/manifest.md
→ For MetaInfo/AppStream XML, see references/metainfo.md
→ For icons and desktop files, see references/icons-and-desktop.md
→ For Flathub submission process, see references/submission.md
Step 1: Choose Your Application ID
The ID follows reverse-DNS format: {tld}.{vendor}.{product}
# Own a domain?
com.example.MyApp
# GitHub/GitLab hosted (REQUIRED format for code hosting)
io.github.yourusername.yourrepo
io.gitlab.yourusername.yourrepo
page.codeberg.yourusername.yourrepo
Rules:
- 3-5 components, max 255 chars
- Characters:
[A-Z][a-z][0-9]_ only (dash - allowed only in last component)
- Do NOT end in
.app, .desktop, .linux
- Must exactly match the ID in your MetaInfo file
- ID determines verification method — choose carefully, renaming requires resubmission
Step 2: Choose a Runtime
| Runtime | SDK | Use for |
|---|
org.freedesktop.Platform//24.08 | org.freedesktop.Sdk//24.08 | Base/minimal apps |
org.gnome.Platform//48 | org.gnome.Sdk//48 | GTK4/GNOME apps |
org.kde.Platform//6.9 | org.kde.Sdk//6.9 | Qt6/KDE apps |
- Freedesktop: new major version every August, 2-year support
- GNOME: synced with GNOME releases (~6 month cycle)
- KDE: synced with Qt releases
- Never use EOL runtimes — submissions will be rejected
Step 3: Write the Manifest
See references/manifest.md for complete examples for each build system.
Minimal YAML manifest skeleton:
id: io.github.yourusername.yourapp
runtime: org.freedesktop.Platform
runtime-version: '24.08'
sdk: org.freedesktop.Sdk
command: your-app-binary
finish-args:
- --share=ipc
- --socket=fallback-x11
- --socket=wayland
- --device=dri
modules:
- name: your-app
buildsystem: cmake-ninja
sources:
- type: git
url: https://github.com/yourusername/yourapp.git
tag: v1.0.0
commit: abc123...
Key manifest rules:
- NO network access during build — all sources must be declared upfront
- No pre-compiled binaries
- All dependencies must be listed as modules or sourced from runtime/shared modules
- Minimize
finish-args — only request what the app actually needs
Step 4: Icons (Critical!)
Icons must be installed at the correct paths. Missing or wrong sizes = linter failure.
Required sizes for Flathub:
/app/share/icons/hicolor/16x16/apps/$APP_ID.png
/app/share/icons/hicolor/32x32/apps/$APP_ID.png
/app/share/icons/hicolor/48x48/apps/$APP_ID.png
/app/share/icons/hicolor/64x64/apps/$APP_ID.png
/app/share/icons/hicolor/128x128/apps/$APP_ID.png
/app/share/icons/hicolor/256x256/apps/$APP_ID.png
/app/share/icons/hicolor/512x512/apps/$APP_ID.png
/app/share/icons/hicolor/scalable/apps/$APP_ID.svg ← SVG preferred
Install icons in your manifest:
- name: your-app
buildsystem: simple
build-commands:
- install -Dm644 icons/512x512.png /app/share/icons/hicolor/512x512/apps/io.github.you.yourapp.png
- install -Dm644 icons/256x256.png /app/share/icons/hicolor/256x256/apps/io.github.you.yourapp.png
- install -Dm644 icons/scalable.svg /app/share/icons/hicolor/scalable/apps/io.github.you.yourapp.svg
See references/icons-and-desktop.md for full guidance including taskbar appearance.
Step 5: Desktop File
[Desktop Entry]
Name=My App
Comment=Short description of what it does
Exec=myapp
Icon=io.github.yourusername.yourapp
Type=Application
Categories=Utility
StartupNotify=true
StartupWMClass=myapp
Install to /app/share/applications/io.github.yourusername.yourapp.desktop
The filename must match your App ID exactly.
Step 6: MetaInfo XML
See references/metainfo.md for the complete required XML structure.
Minimum required tags: id, name, summary, description, metadata_license,
project_license, developer, launchable, screenshots, releases, content_rating
Step 7: Build and Test Locally
flatpak install -y flathub org.flatpak.Builder
flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak run --command=flathub-build org.flatpak.Builder --install io.github.you.yourapp.yaml
flatpak run io.github.you.yourapp
flatpak run --command=flatpak-builder-lint org.flatpak.Builder manifest io.github.you.yourapp.yaml
flatpak run --command=flatpak-builder-lint org.flatpak.Builder repo repo
Fix all linter errors before submitting. Both errors AND warnings are fatal.
Step 8: Submit to Flathub
See references/submission.md for the complete PR workflow.
TL;DR:
- Fork
flathub/flathub on GitHub (uncheck "master branch only")
- Clone with
--branch=new-pr
- Create a new branch, add your files, push
- Open PR against the
new-pr base branch (NOT master)
- Title:
"Add io.github.you.yourapp"
Common Linter Failures
| Error | Fix |
|---|
| Missing MetaInfo | Create $APP_ID.metainfo.xml |
| Wrong icon path | Name must exactly match $APP_ID, not just app name |
Missing content_rating | Add <content_rating type="oars-1.1" /> |
| EOL runtime | Update to current runtime version |
| Network in build | Remove network calls, pre-vendor all deps |
| Desktop file mismatch | Filename must be $APP_ID.desktop |
| Missing release tag | Add at least one <release> entry |
| Icon too small | Provide at least 128x128, ideally up to 512x512 |
Sandbox Permissions Cheatsheet
Only request what you need. Prefer XDG portals over static permissions.
finish-args:
- --socket=wayland
- --socket=fallback-x11
- --share=ipc
- --device=dri
- --filesystem=home
- --filesystem=xdg-documents
- --filesystem=xdg-pictures
- --filesystem=host:ro
- --socket=pulseaudio
- --share=network
- --talk-name=org.freedesktop.Notifications
- --own-name=com.example.MyApp
Use portals instead of --filesystem=home wherever possible.