Skip to main content

Introduction to Flatpak

Flatpak is one of app sandboxing frameworks, along with AppImage and Snap 1. Although Snap is the most famous one, I think the internal architecture of Flatpak is more reliable.

Fedora Silverblue and EndlessOS provide software installation primarily via Flathub, a central repository of Flatpak based applications 2 3.

This post briefly summarizes how to use Flatpak in terms of implementing a sample applications.

Installing Flatpak #

In Ubuntu distributions, there is no Flatpak preinstalled, while it is in Fedora. Follow [this setup guide] for Ubuntu:

# Need to add the PPA for older versions (<18.10) of Ubuntu.
$ sudo apt install flatpak

Then add the Flathub repository:

flatpak remote-add --if-not-exists flathub

Installing Flatpak Applications #

It seems Flathub Github repository contains all (not sure) Flatpak applications. I would like to install com.visualstudio.code.

Installing from Flathub #

Simply, you can install the application via:

$ flatpak install flathub com.visualstudio.code


  • flatpak install: indicates that I want to install an applicatin.
  • flathub: the name of remote; we performed flatpak remote-add flathub ... above, so this indicates it should download the application from the specified flathub repository.
  • com.visualstudio.code: the name of the application.

Thankfully, it automatically installs all dependent runtimes and SDKs.

        ID                                              Branch            Op           Remote            Download
 1.     org.freedesktop.Platform.GL.default             19.08             i            flathub            < 89.1 MB
 2.     org.freedesktop.Platform.VAAPI.Intel            19.08             i            flathub             < 8.7 MB
 3.     org.freedesktop.Platform.openh264               2.0               i            flathub             < 1.5 MB
 4.     org.freedesktop.Sdk.Locale                      19.08             i            flathub           < 322.4 MB (partial)
 5.     org.gtk.Gtk3theme.Yaru-dark                     3.22              i            flathub           < 171.3 kB
 6.     org.freedesktop.Sdk                             19.08             i            flathub           < 578.9 MB
 7.     com.visualstudio.code                           stable            i            flathub            < 63.8 MB

Proceed with these changes to the system installation? [Y/n]:

Installing from Source Code #

If you want to modify the project and test it, you can download, build, install, and run the application from the source code. To build an application, we use flatpak-builder:

$ git clone
$ cd com.visualstudio.code; mkdir build
$ git submodule update --init
$ flatpak-builder build com.visualstudio.code.yaml


  • build: the name of target directory. Built data will be placed in here.
  • com.visualstudio.code.yaml: the name of the manifest. Flatpak apps should have their own manifest as a JSON or YAML format 4. Steam contains com.visualstudio.code.yml manifest in its root directory.

flatpak-builder does not install dependent packages, nor install the built package. Use the following options:

  • --install: automatically install the package if build succeeds
  • --install-deps-from=REMOTE: automatically install the dependent packages from REMOTE (in our case, REMOTE=flathub).
$ flatpak-builder build --install --install-deps-from=flathub com.visualstudio.code.yaml
Installing app/com.visualstudio.code/x86_64/stable
$ flatpak run com.visualstudio.code
Microsoft Visual Studio Code running with Flatpak.

--install flag installs build contents to:

  • build/export -> /var/lib/flatpak/app/<application_name>/<arch>/<tag>/<hash>/export
  • build/files -> /var/lib/flatpak/app/<application_name>/<arch>/<tag>/<hash>/files
  • Have no idea what build/var is for (empty).

Application Structure #

According to the Flathub wiki 5, a manifest file is the only required file for an application. it contains everything how to build the specified application.

  • If the application is com.example.MyApp, the manifest file must be com.example.MyApp.json or com.example.MyApp.yaml.
  • This manifest may import other manifest files by adding a shared-modules Git submodule.

Commonly used shared modules are packed to Flathub shared module, and can be found in [here]. Choose submodules among the subdirectories in the repository, and specify it in modules of the application manifest, like in JSON:

"modules": [

or in YAML:

  - shared-modules/libsecret/libsecret.json

Sources and Build Commands #

So the only required file is the manifest. It should also contain how to build an application: build-commands is for this purpose. Also the source files are required; insteading of packaging them together in a repository, Flatpak requires to specify them as sources in the manifest.

    - shared-modules/libsecret/libsecret.json

    - name: vscode
      buildsystem: simple
        - install -D /app/bin/code
        - install -Dm644 vscode_64.png /app/share/icons/hicolor/64x64/apps/com.visualstudio.code.png
      - type: script
        dest-filename: apply_extra
          - ar x code.deb
          - tar xf data.tar.xz
          - mv usr/share/code vscode
          - rm -r code.deb control.tar.gz data.tar.xz debian-binary usr
      - type: file
      - type: file
        path: flatpak-warning.txt

Please refer to [here] for more details about how to add modules.

Runtime and SDK #

Flatpak packs commonly used packages into runtime and SDK, so that they do not have to unnecessarily be duplicated. All applications depend on a runtime.

runtime: org.freedesktop.Sdk
runtime-version: '19.08'
sdk: org.freedesktop.Sdk

Available runtimes are listed in [here] I am figuring out how to build a custom runtime, and will upload another post regarding it later.

Exploring Container Inside #

Now let’s go inside the running container. Flatpak uses bubblewrap to create an isolated container.

Here is an interesting post from Open Container Initiative, describing why Flatpak uses bubblewrap instead of runc, a famous low-level container runtime used by CRI-O or Docker.

We can use flatpak enter command to enter the running container, however, there was a bug regarding flatpak enter command that returns an error: Can't enter user namespace: Invalid argument 6. As Ubuntu 20.04 LTS contains flatpak version 1.6.5, we need an update to at least 1.8.0 for fix. I installed flatpak-1.8.x branch in Flatpak Github repository (currently version 1.8.2) and with the following commands you can enter the container:

$ flatpak run com.visualstudio.code
$ flatpak ps
Instance   PID     Application           Runtime
3503674006 1931892 com.visualstudio.code org.freedesktop.Sdk
$ flatpak enter 1931892 /bin/sh
[📦 com.visualstudio.code com.visualstudio.code]$

The entry point of Flatpak is defined as command in the manifest, like command: code in vscode. While I could find any reference how default environmental variables are set, however, it seems $PATH is set /app/bin:/usr/bin by default, hence the command code is interpreted as /app/bin/code and executed, which is actually (refer to build-commands: install -D /app/bin/code).

  1. AppImage: Comparison to the other Solutions ↩︎

  2. Fedora Silverblue: Getting Started: Flatpak ↩︎

  3. EndlessOS: What’s Flatpak? ↩︎

  4. Flatpak: Manifests ↩︎

  5. Flathub: App Maintenance ↩︎

  6. Flatpak: error: Can’t enter user namespace: Invalid argument ↩︎