| # Developing with Fuchsia packages | 
 |  | 
 | Almost everything that exists on a Fuchsia system is a [Fuchsia package][pkg-struct]. | 
 | Whether it is immediately apparent or not almost everything you see on | 
 | Fuchsia lives in a package. This document will cover the basics of a | 
 | package-driven workflow where you [build][pkg-doc] a package and push it to a | 
 | Fuchsia device that is reachable via IP from your development host. | 
 |  | 
 | ## Pre-requisites and overview | 
 |  | 
 | The host and target must be able to communicate over IP. In particular | 
 | it must be possible to SSH from the development host to the target device, and | 
 | the target device must be able to connect via TCP to the development host on | 
 | port 8083. The SSH connection is used to issue commands to the target device. | 
 |  | 
 | The development host will run a simple, static file, HTTP server that makes the | 
 | updates available to the target. This HTTP server is part of the Fuchsia source | 
 | code and built automatically. | 
 |  | 
 | The target is instructed to look for changes on the development host via a | 
 | couple of commands that are run manually. When the update system on the target | 
 | sees these changes it will fetch the new software from the HTTP server running | 
 | on the host. The new software will be available until the target is rebooted. | 
 |  | 
 | ## Building | 
 |  | 
 | <!-- TODO(jmatt): improve to talk about wider variety of build options --> | 
 |  | 
 | To build a package containing the required code, a package type build rule is | 
 | used. If one of these needs to be created for the target package, consult the | 
 | reference [page][pkg-doc] for this. | 
 |  | 
 | Once an appropriate build rule is available the target package can be | 
 | re-generated by running `fx build`. | 
 |  | 
 | ## Connecting host and target | 
 |  | 
 | The Fuchsia source contains a simple HTTP server that serves static files. The | 
 | build generates and serves a [TUF][TUF-home] file tree. | 
 |  | 
 | The update agent on the target does not initially know where to look for | 
 | updates. To connect the agent on the target to the HTTP server running on the | 
 | development host, it must be told the IP address of the development host.  The | 
 | host HTTP server is started and the update agent is configured by calling `fx | 
 | serve -v`.  `fx serve` will run the update server and is often what people use. | 
 | `-v` is recommended because the command will print more output, which may assist | 
 | with debugging. If the host connects successfully to the target you will see the | 
 | message `Ready to push packages!` in the shell on your host. | 
 |  | 
 | The update agent on the target will remain configured until it is repaved or | 
 | persistent data is lost. The host will attempt to reconfigure the update agent | 
 | when the target is rebooted. | 
 |  | 
 | ## Triggering package updates | 
 |  | 
 | Packages in Fuchsia are not "installed", they are cached on an as needed | 
 | basis. There are two collections of packages on a Fuchsia system: | 
 |  | 
 | * **base** The `base` package set is a group of software critical to proper | 
 |   system function that must remain congruent. The Fuchsia build system | 
 |   assigns packages to `base` when they are provided to `fx set` using the | 
 |   `--with-base` flag. | 
 |   This set of software can only be updated by performing a whole system update, | 
 |   typically referred to as OTA, described below. This is updated using `fx ota`. | 
 |  | 
 | * **ephemeral software** Packages included in the `cache` or `universe` package | 
 |   set are ephemeral software, with updates delivered on demand. The Fuchsia | 
 |   build system assigns packages to `universe` when they are provided to `fx set` | 
 |   using the `--with` flag. | 
 |   Ephemeral software updates to the latest available version whenever the | 
 |   package URL is resolved. | 
 |  | 
 | ## Triggering an OTA | 
 |  | 
 | Sometimes there may be many packages changed or the kernel may change or there | 
 | may be changes in the system package. To get kernel changes or changes in the | 
 | system package an OTA or [pave][paver] is *required* as **base** packages are | 
 | immutable for the runtime of a system. An OTA update will usually be faster | 
 | than paving or flashing the device. | 
 |  | 
 | The command `fx ota` asks the target device to perform an update from any of | 
 | the update sources available to it. To OTA update a build made on the dev host to | 
 | a  target on the same LAN, first build the system you want. If `fx serve [-v]` | 
 | isn't already running, start it so the target can use the development host as an | 
 | update source. The `-v` option will show more information about the files the | 
 | target is requesting from the host. If the `-v` flag was used there should | 
 | be a flurry of output as the target retrieves all the new files. Following | 
 | completion of the OTA the device will reboot. | 
 |  | 
 | ## Just the commands | 
 |  | 
 | * `fx serve -v` (to run the update server for both build-push and ota) | 
 | * `fx run <component-url>` (each time a change is made you want to run) | 
 | * `fx test <component-url>` (to build and run tests) | 
 | * `fx ota` (to trigger a full system update and reboot) | 
 |  | 
 | ## Issues and considerations | 
 |  | 
 | ### You can fill up your disk | 
 |  | 
 | Every update pushed is stored in the content-addressed file system, blobfs. | 
 | Following a reboot the updated packages may not be available because the index | 
 | that locates them in blobfs is only held in RAM. The system currently does not | 
 | garbage collect inaccessible or no-longer-used packages (having garbage to | 
 | collect is a recent innovation!), but will eventually. | 
 |  | 
 | The command `fx gc` will reboot the target device and then evict all old | 
 | ephemeral software from the device, freeing up space. | 
 |  | 
 | ### Restarting without rebooting | 
 |  | 
 | If the package being updated hosts a service managed by Fuchsia that service | 
 | may need to be restarted. Rebooting is undesirable both because it is slow and | 
 | because the package will revert to the version paved on the device. Typically | 
 | a user can terminate one or more running components on the system, either by | 
 | asking the component to terminate gracefully, or by forceufully stopping the | 
 | component using `fx shell killall <component-name>`. Upon reconnection to the | 
 | component services, or by invocation via `fx run` or `fx test`, new versions | 
 | available in the package server will be cached before launch. | 
 |  | 
 | ### Packaging code outside the Fuchsia tree | 
 |  | 
 | Packaging and pushing code that lives outside the Fuchsia tree is possible, but | 
 | will require more work. The Fuchsia package format is quite simple. It consists | 
 | of a metadata file describing the package contents, which is described in more | 
 | detail in the [Fuchsia package][pkg-struct] documentation. The metadata file is | 
 | added to a TUF file tree and each of the contents are named after their Merkle | 
 | root hash and put in a directory at the root of the TUF file tree called 'blobs'. | 
 |  | 
 | [pkg-struct]: /src/sys/pkg/bin/pm/README.md#structure-of-a-fuchsia-package "Package structure" | 
 | [TUF-home]: https://theupdateframework.github.io "TUF Homepage" | 
 | [pkg-doc]: /docs/development/build/build_system/fuchsia_build_system_overview.md "Build overview" | 
 | [paver]: /docs/development/build/fx.md#what-is-paving "Fuchsia paving" |