Format overview

An AppImage is an ISO 9660 file with zisofs compression containing a minimal AppDir (a directory that contains the app and all the files that it requires to run which are not part of the targeted base operating systems) and a tiny runtime executable embedded into its header. Hence, an AppImage is both an ISO 9660 file (that you can mount and examine) and an ELF executable (that you can execute).

When you execute an AppImage, the tiny embedded runtime mounts the ISO file, and executes the app contained therein.

A minimal AppImage could potentially look like this:

----------------------------------------------------------
|            |                                           |
| ELF        | ISO9660 zisofs compressed data containing |
| embedded   | AppRun                                    |
| in ISO9660 | .DirIcon                                  |
| header     | SomeAppFile                               |
|            |                                           |
---------------------------------------------------------
  1. AppRun is the binary hat is executed when the AppImage is run

  2. .DirIcon contains a 48x48 pixel PNG icon that is used for the AppImage

  3. SomeAppFile could be some random file that the app reqires to run

However, in order to allow for automated generation, processing, and richer metadata, the AppImage format follows a somewhat more elaborate convention:

----------------------------------------------------------
|            |                                           |
| ELF        | ISO9660 zisofs compressed data containing |
| embedded   | AppRun                                    |
| in ISO9660 | appname.desktop                           |
| header     | usr/bin/appname                           |
|            | usr/lib/libname.so.0                      |
|            | usr/share/icons/*/48x48/apps/iconname.png |
|            | usr/share/appname/somehelperfile          |
|            | .DirIcon                                  |
|            |                                           |
---------------------------------------------------------
  1. The ELF embedded in the ISO9660 header always executes the file called AppRun inside the ISO9660 file.

  2. The file AppRun inside the ISO9660 file is not the actual executable, but instead a tiny helper binary that finds and exectues the actual app. Generic AppRun files have been implemented in bash and C as parts of AppImageKit. The C version is generally preferred as it is faster and more portable.

  3. AppRun usually does not contain hardcoded information about the app, but instead retrieves it from the file appname.desktop that follows the Desktop File Specification.

    A minimal appname.desktop file that would be sufficient for AppImage would need to contain

    [Desktop Entry]
    Name=AppName
    Exec=appname
    Icon=iconname

    This desktop file would tell the AppRun executable to run the executable called appname, and would specify AppName as the name for the AppImage, and iconname.png as its icon.

    However, it does not hurt if the desktop file contains additional information. Should it be desired to provide additional metadata with an AppImage, the desktop file could be extended with X-AppImage-... fields as per the Desktop File Specification. Usually, desktop files provided in deb or rpm archives are suitable to be used in AppImages. However, abolute paths in the Exec statement are not supported by the AppImage format.

  4. The AppImage contains the usual usr/ hierarchy (following the File Hierarchy Standard). In the concrete example from the desktop file above, the AppRun executable would look for usr/bin/appname and would execute that. Also, the AppImageKitAssistant (a tool used to create AppImages easily) would look for usr/share/icons/*/48x48/iconname.png and use that as the .DirIcon file, effectively making it the icon of the AppImage.

  5. The app must be programmed in a way that allows for relocation. In other words, the app must not have hardcoded paths such as /usr/bin, /usr/share, /etc inside the binary. Instead, it must use relative paths, such as ./bin.

    Since most binaries contained in deb and rpm archives generally are not created in a way that allows for relocation, they need to be either changed and recompiled (e.g., using the binreloc framework), or the binaries need to be patched. As recompiling is not convenient in most cases, AppRun changes to the usr/ directory prior to executing the app, enabling the app to specify all paths relative to the AppImage's usr/ directory. This allows one to use patched binaries (where the string /usr has been replaced with the same-length string ././, which means "current directory"). AppImageKit comes with a tool that does this automatically. Note that if you use the ././ patch, then your app must not use chdir, or otherwise it will break.

  6. The ELF embedded in the ISO9660 header contains an icon embedded into the ELF executable following the elficon specification. AppImageKitAssistant would automatically embed the specified icon.

Note that the AppImage format has been conceived to facilitate the conversion of deb and rpm packages into the AppImage format with minimal manual effort. Hence, it contains some conventions in addition to those specified by the AppDir format, to which it is compatible to the extent that an unpacked AppImage can be used as an AppDir with the ROX Filer.