A packaged app is an Open Web App that has all of its resources (HTML, CSS, JavaScript, app manifest, and so on) contained in a zip file, instead of having its resources on a Web server. This article covers everything you need to know about packaged apps from a developer standpoint.

A packaged app is simply a zip file with the app manifest in its root directory. The manifest must be named manifest.webapp. One difference from a hosted app is that a packaged app must specify a launch_path in the manifest, whereas it's an optional manifest field for a hosted app.

Purpose of packaged apps

The purpose of a packaged app is to have a workable way to provide apps that have access to sensitive APIs on devices. The app must be verified by the store where the app is distributed (such as the Firefox Marketplace). The store reviews the app and if it is found acceptable, the store cryptographically signs the app's zip file with its private key. This gives users of the app more assurance that the app has been carefully reviewed for potential security, privacy, and capability issues.

Types of packaged apps

There are three types of packaged apps:

Privileged app

A privileged app is approved by the Firefox Marketplace using a special process. It is meant to provide more safety for users when an app wants access to certain sensitive APIs on a device. It is equivalent to a native app on a platform like iOS or Android. To specify that an app is a privileged app, add the type field to its manifest.webapp file and set it to privileged.

Implements other requirements related to security. See Security for more information.

Certified app

A certified app is intended for a critical system function like the default dialer or the system settings app on a smartphone. This type of app would be used for critical functions on a Firefox OS phone. It is not intended for third party apps, so most app developers cannot use this type of app. A certified app is a packaged app that is similar to a privileged app, except that all device permissions are implicit, meaning they are enabled without explicit user approval. A certified app must be approved for a device by the OEM or carrier in order to have this implicit approval to use critical APIs. To specify that an app is a certified app, add the type field to its manifest.webapp file and set it to certified.

The following is the CSP for a certified app, which is slightly different from the CSP for a privileged app:

This has the effect of slightly looser rules for inline CSP for privileged apps when compared to certified apps. If you want more of the reasoning behind this, see Default CSP policy and Bug 768029.

Plain packaged app

You can also make a regular app that is simply packaged in a zip file. The Marketplace signs it, but does not perform the special authentication process used for privileged or certified apps. This plain packaged app cannot use certain sensitive Web APIs. It is not subject to the CSPs described for privileged and certified apps. This type of app could be useful if you want all of your app's resources available on the device when the user first uses it, with no downloading. This type of packaged app does not require the type field in its manifest.webapp file, because the default value for type (web) is correct.

Using sensitive Web APIs

There are Web APIs that could be used maliciously, so access to them must be controlled. For every sensitive API you want your app to access, you must add an entry to the permissions field in the app's manifest.

Some sensitive APIs can be accessed by normal hosted apps, but other APIs require that you use a packaged app (privileged or certified). See App permissions for a table that describes the requirements.

Packaged apps and the Firefox Marketplace

The Firefox Marketplace handles packaged apps differently from hosted apps. When you submit your packaged app, its zip file is stored on the Marketplace servers, and the Marketplace generates a new manifest called the "mini-manifest" that is based on the app manifest in your packaged app's zip file. When a user installs your app, the mini-manifest is passed to the installPackage() function to install the app. The mini-manifest exists for installation and update purposes and is not used when your app runs.

Testing packaged app installation

To install a packaged app on a Firefox OS device using the Simulator for testing purposes, see the section on "Push to Device" in the Simulator guide. To test a packaged app without the Simulator, you can install it on a device from a regular web server by following the steps below, in the Self-publishing packaged apps section.

Self-publishing packaged apps

You can self-publish a packaged app by hosting it on a server along with a mini-manifest in the same directory that identifies the app and is used in the install process. This section covers how to do this detail.

Note that you can also host a packaged app locally and test it on a real device. The Web server and the phone must be on the same network, and the server must be able to serve requests from the local network. You just need to include the absolute path to the referenced files, in the same way as the absolute paths are included normally (see below.) Remember to include the port information if you are using a non-standard port, for example http://10.10.12.1:8080/package.zip.

Steps

Zip up your app's contents and give it the name package.zip. This file should contain all the app's resource files, including the manifest.

Caution: You must be also careful to zip the contents you wish to appear in the packaged app, and not the directory they are contained in. If you zip up the parent directory, the manifest will end up in the wrong place, and the packaged app will be invalid.

Create a file called package.manifest and give it the contents below. This is a mini-manifest used for packaged app installation purposes. It is not the main manifest of your app that is inside the zip file. See Mini-manifest fields if you want more detailed information about mini-manifests.

Using a compatible device (such as a Firefox OS phone), navigate to the location on your server where you put the example files and confirm the prompt to install the app. The script will give an indication of installation success or failure.

Note: You can not install privileged or certified apps with installations from hosted packages, as they need to be signed. Use the Simulator to test privileged apps.

When the Firefox Marketplace generates a mini-manifest for your app, it pulls information from your app's manifest for some of the fields. You can find documentation for these fields at App manifest. The fields unique to the mini-manifest are package_path, release_notes, and size. The name, version, developer, and locales fields in your app manifest must be exactly the same as in your mini-manifest.

Here is information on the mini-manifest that relates to using it locally for your own testing:

name

(required) The app's name. Maximum length is 128 characters.

package_path

(required) The URL where the app's zip file can be found. You need to make sure the package_path is absolute to where the ZIP file is located.

version

The version of the app.

size

The size of the app's zip file in bytes. This is not necessary for local testing, but provide it to get a progressbar during installation.

release_notes

Information about this release of the app. On the Marketplace this information comes from a Web page that is part of the submission process.

developer

Information about the developer, contains the name and url fields. The developer info needs to match between the mini-manifest and the main manifest file in the ZIP.

locales

Localization information. Keys should be in xx-YY format.

icons

Icons for use by the app.

Note: Values in package and webapp.manifest need to be the same, otherwise installation will fail. The safest way is to copy manifest.webapp into package.manifest and just add the package_path.

Differences from hosted apps

Packaged apps have the same capabilites as normal website-style Open Web Apps ("hosted" apps), but packaged apps have a few differences:

They have no Internet origin. The one-app-per-origin policy that governs hosted apps does not apply to packaged apps.

They use a special protocol internal to the zip file: app://<uuid>. Example: When you load the content /index.html in a packaged app, you are actually loading something like the following (the UUID will be different):

app://550e8400-e29b-41d4-a716-446655440000/index.html

The UUID is randomly generated at install time, which means that it is unique per device it is installed on. The app:// protocol will be useful in future releases of the Web runtime for some identity, payment and OAuth flows.

Their resources are accessed from the zip file, which is stored on the device where the app is installed.

For a self-hosted packaged app, you need to include an additional mini-manifest in the same directory as the zipped packaged app, which doesn't need to be called manifest.webapp (you might call it something like package.webapp). See Self-publishing packaged apps above for more details.

They are installed with a different mozApps API function, installPackage(), which for a self-hosted packaged app must point to the mini-manifest.

They enforce a specific CSP for all application content (a hosted app could also use a CSP, but it is not required).

They can embed remote content in iframes, but that content will not have access to privileged APIs nor will it have the default CSP applied to it.

They have an update process for getting new versions of the app to users. Hosted apps do not need this process.

The packaged app can still do things like access a database on a Web server, like a regular hosted app.