A package is the unit of installation on a Fuchsia system. This document describes
various workflows for building and installng a package.

> [!NOTE]
> **Note:** The majority of these workflows rely on the `ffx` tool which is available in `//tools`.

The workflows are:

- [Build a package](https://fuchsia.dev/fuchsia-src/development/idk/documentation/packages#build-package)
- [Publish a package](https://fuchsia.dev/fuchsia-src/development/idk/documentation/packages#publish-package)
- [Install a package](https://fuchsia.dev/fuchsia-src/development/idk/documentation/packages#install-package)
- [Run a component from an installed package](https://fuchsia.dev/fuchsia-src/development/idk/documentation/packages#run-component)

For more details, see the help messages from `ffx package build help`,
and `ffx repository publish help`.

## Build a package

To build a package:

1. Create a `meta` directory:

       mkdir -p PACKAGE_DIR/meta

   Replace <var translate="no">PACKAGE_DIR</var> with the staging directory where the package
   is going to be built.
2. Set the `$META_PACKAGE_FILE` environment variable:

       export META_PACKAGE_FILE=PACKAGE_DIR/meta/package

3. Open a text editor and create the `$META_PACKAGE_FILE` file with
   the following content:

       {
         "name": "<intended name of your package here>",
         "version": "0"
       }

   The version number is currently required to be `0`.
4. Save the file and close the text editor.

5. Create a [package build manifest file](https://fuchsia.dev/docs/development/build/gn_concepts/internals/manifest_formats) (`$BUILD_MANIFEST_FILE`),
   which provides the paths to all the package content files, and export its
   path via the variable:

       export BUILD_MANIFEST_FILE=BUILD_MANIFEST_FILE

   Each line of a manifest file maps to a file contained in the package and
   is in the form of `destination=source` where:
   - `destination` is the path to the file in the final package.
   - `source` is the path to the file on the host machine.

   The manifest file must include at least one line for the package ID file,
   for example:

       meta/package=/path/to/meta/package

   Additional files to be added to the package must be listed in the build
   manifest file in the same way.
6. Go to the <var translate="no">PACKAGE_DIR</var> directory:

       cd PACKAGE_DIR

7. Generate a package manifest file, which creates the package metadata archive
   at <var translate="no">PACKAGE_DIR</var>`/meta.far`:

       ffx package build $BUILD_MANIFEST_FILE -o PACKAGE_DIR --api-level HEAD

   This command creates the package manifest file implicitly as
   <var translate="no">PACKAGE_DIR</var>`/package_manifest.json`.

   Note that the `--api-level` is preferably used to target a specific API
   level, given by a numeric argument. In this example we use HEAD, i.e. the
   latest in-development API.
8. Set the `$PACKAGE_MANIFEST_FILE` environment variable:

       export PACKAGE_MANIFEST_FILE="PACKAGE_DIR/package_manifest.json"

   If the contents of the package change, you need to re-run the
   `ffx package build $BUILD_MANIFEST_FILE` command.
9. Create a package archive, which gathers all the package contents into
   a single distributable file:

       ffx package archive create -o "PACKAGE_DIR/PACKAGE_NAME.far" "$PACKAGE_MANIFEST_FILE"

   Replace <var translate="no">PACKAGE_NAME</var> with the intended name of the package.

   This command creates the package archive as <var translate="no">PACKAGE_NAME</var>`.far`.
10. Set the`$PACKAGE_ARCHIVE` environment variable:

        export PACKAGE_ARCHIVE=PACKAGE_DIR/PACKAGE_NAME.far

    If the contents of the package change, you need to re-run the
    `ffx package build` and `ffx package archive create` commands.

You have successfully built a package. Now you are ready to publish the package.

## Publish a package

> [!NOTE]
> **Note:** The workflow in this section uses the environment variables set in the previous [Build a package](https://fuchsia.dev/fuchsia-src/development/idk/documentation/packages#build-package) section.

To publish a package:

1. Initialize a directory that serves as a packages repository:

       ffx repository create REPO

   This creates a directory structure under the directory <var translate="no">REPO</var> which
   is ready for publishing packages.
2. Publish package manifests to the repository:

       ffx repository publish --package $PACKAGE_MANIFEST_FILE REPO

   `ffx repository publish` parses `$PACKAGE_MANIFEST_FILE` and publishes the
   package in the provided <var translate="no">REPO</var> directory.

   The `--package` argument can be repeated. If you run this command multiple
   times with different package manifests, each instance will be published to
   the same repository. New versions of the same packages can be published using
   the same command.
3. (Optional) Publish package archives to the repository:

       ffx repository publish --package-archive $PACKAGE_ARCHIVE REPO

   `ffx repository publish` parses `$PACKAGE_ARCHIVE` and publishes the
   package in the provided <var translate="no">REPO</var> directory.

   The `--package-archive` argument can be repeated. If you run this command
   multiple times with different package archives, each instance will be
   published to the same repository. New versions of the same packages can be
   published using the same command.

You have successfully published a package. You are now ready to install a
package.

## Install a package

To install a package:

1. Start the package server and serve the repository to the target:

       ffx repository serve --repository "REPO_NAME" --repo-path "REPO"

   By default, this starts a repository server on the host machine, listening on
   port `8083`. This introduces the repository to the target as an update
   source. The `--repository "REPO_NAME"` is optional, but useful.
2. (On the target device) Check the configured repository:

       pkgctl repo -v

   You should see a repository configured, listing (among other configuration
   variables) its repository url `"repo_url": "fuchsia-pkg://<REPO_NAME>"`.
3. Download the package:

       ffx target package resolve fuchsia-pkg://REPO_NAME/PACKAGE_NAME

   If the component is not already present on the system, the package resolver
   on the target device downloads the package and places the blobs in the
   blobFS. If the package already exists but a newer package is available on the
   package server, the updates will be downloaded.

   > [!NOTE]
   > **Note:** If you work on an older version of Fuchsia, `ffx target package` might not be available, and the above command will error out. If this is the case, run the following command **on the target device shell** as a fallback: `pkgctl resolve fuchsia-pkg://REPO_NAME/PACKAGE_NAME`

You have successfully installed or updated the package. You are now ready to
run a component from the installed package.

## Run a component from an installed package

To run the component, use the `ffx component run` tool. For help: `ffx component run --help`.

For the `url` parameter provide a URL in the form of
`fuchsia-pkg://<REPO_NAME>/<PACKAGE_NAME>#meta/<COMPONENT_NAME>.cm`.
[](https://issues.fuchsia.dev/issues/new?component=1439230&template=1881640&description=Issue+on:+https://fuchsia.dev/docs/development/idk/documentation/packages.md "Report a bug or suggest improvements on this page") [](https://cs.opensource.google/fuchsia/fuchsia/+/main:docs/development/idk/documentation/packages.md "View the source code of this page") [](https://ci.android.com/edit?repo=fuchsia/fuchsia/main&file=docs/development/idk/documentation/packages.md&cloneRepo=fuchsia/fuchsia:refs/heads/main&fullPath=fuchsia/docs/development/idk/documentation/packages.md "Edit the source code of this page")