---
title: "Universal Feeds & Packages"
order: 3
---

The Universal Package format is very simple and can be used to package applications and components built with any technology: ASP.NET websites, NodeJS applications, Windows services, plug-ins for your applications, system configuration scripts, and so on. 

Universal Packages are designed both for general use and as a platform for creating a new proprietary package format. You can also extend the manifest file of a universal package with additional metadata (and then search based on that metadata).

## Creating Universal Packages { #upack-create }

There are several ways to create and publish Universal Packages. These include using the [pgutil](/docs/proget/api/pgutil) CLI tool to create a package and then uploading it using The [Upload Universal Packages](/docs/proget/api/universal-feed/upload) endpoint in the [Universal Feed API](/docs/proget/api/universal-feed), or uploading hand-crafted package files through the ProGet UI. To learn more about this, read [HOWTO: Create Universal Packages]()

### Using pgutil

You can create packages using the [pgutil](/docs/proget/api/pgutil) CLI tool, using the `upack create` command:

```bash
$ pgutil upack create --name=«package-name» --version=«package-version» --source-directory=«package-file-directory» --target-directory=«package-target-directory»
```
`source-directory` will be the location of the files you want to create a Universal Package with, and `target-directory` will be the location you want to save your newly created Universal Package to.

Alternatively, if you have already created a `upack.json` manifest for your Universal Package, you can specify this instead:

```bash
$ pgutil upack create --manifest=«upack-json-file» --source-directory=«package-file-directory» --target-directory=«package-target-directory»
```

Once created, you can upload your Universal Package to ProGet using the [Upload Universal Packages](/docs/proget/api/universal-feed/upload) endpoint in the [Universal Feed API](/docs/proget/api/universal-feed):

```bash
$ curl -X POST -H "X-ApiKey: «api-key»" http://«proget-url»/upack/«feed-name»/upload --upload-file «upack-file»
```

### Using the ProGet UI

You can create and upload Universal Packages directly through the ProGet user interface. This method is useful for those who prefer the simplicity of a UI vs using CLI, and for packages with infrequent releases where automation isn't required.

Navigate to a Universal Package feed and select "Add Package" from the drop-down menu. Then select "Create a Package". After entering details such as name and version, you can use the UI to either drag and drop or select files. 

![](/resources/docs/proget-upack-createpackage.png){height="" width="50%"}

From here, select "Create Package" to create and upload your newly created Universal Package to ProGet.

## Editing Packages

Universal Packages uploaded to ProGet can be edited. We strongly discourage editing Universal Packages after they have been published as they are designed to be immutable to ensure integrity and reproducibility, and doing so can lead to unexpected behavior.

However, downloading, editing, and uploading a package as a new version can be frustrating when only minor changes are needed, for example, minor edits to the metadata like tags or description. ProGet lets you make edits to a Universal Package's manifest `.json` through the UI. Navigate to a package and select "Edit Package" from the dropdown menu. This will open a window allowing you to make changes:

![](/resources/docs/proget-upack-editpackage.png){height="" width="50%"}

## Downloading Universal Packages & Package Content

There are two possible options when downloading a Universal Package:

* Download a Package in a Universal Package format, including it's metadata
* Download only the files packaged in a Universal Package as a `zip` or `tgz` file. 

Downloading can be performed either through the UI or as a CLI command. To download only the contents of a Universal Package, add the query parameter `?contentOnly` to the URL and specify either `zip` or `tgz` as a value. For example:

```bash
$ curl https://«proget-url»/upack/«feed-name»/download/MyPackage/1.2.3?contentOnly=zip --output MyPackage-1.2.3.zip --user «user»:«password»
```

## Installing Universal Packages

You can use [pgutil](/docs/proget/api/pgutil) to install Universal Packages using the `upack install` command. This will install the files to the specified location and create an entry in the Universal Package Registry:

```bash
$ pgutil upack install --package=«package-name» --version=«package-version» --feed=«feed-name» --target=«install-location»
```

### The Universal Package Registry { #upack-registry }

The Universal Package Registry is a local system designed to track and manage packages installed using pgutil. It records metadata like package name, version, etc, ensuring traceability and compliance. It operates in machine-level, user-level, and custom contexts, with each registry consisting of a metadata file (`installedPackages.json`) and an optional package cache for auditing, repair, and staging.

For example, if a package named `MyPackage 1.2.3` is installed, the registry will record metadata such as its installation date, installation path and the person who installed it. The package cache might store `my-package.1.2.3.upack` in a structured directory, allowing the package to be reinstalled without re-downloading. This maintains consistency and lets you audit and repair installations if needed.

To view the metadata of any installed Universal Packages, you can use the `upack list` pgutil command. This will list all packages installed:

```bash
Name: MyPackage
Version: 1.0.0
Install Path: C:\Production\UniversalPackages
Installed On: 2025-02-20T16:52:04.1484994+09:00 by j-smith

Name: TestPackage
Version: 1.2.3
Install Path: C:\TestData\UniversalPackages
Installed On: 2025-02-20T16:53:14.9907086+09:00 by m-jones
```

You can read more about the Universal Package Registry in the [Inedo.UPack](https://github.com/inedo/inedo.upack/blob/master/registry.md) repository.

### Updating and Removing Installed Packages

You can also use pgutil to either update or remove any installed packages. Using the `upack update` command will update a Universal Package installation with another specified version from your Universal Package feed:

```bash
$ pgutil upack update --package=«package-name» --version=«package-version» --feed=«feed-name»
```
 
Using the `upack remove` command will uninstall a Universal Package:

```bash
$ pgutil upack remove --package=«package-name»
```
 
## Authenticating to Universal Package Feeds { #authentication }

To upload packages, or download or install them if a feed has been configured to require authentication, you will need a username/password combination. However, we strongly recommend [Creating a ProGet API Key](/docs/proget/api/apikeys) instead. When using [pgutil](/docs/proget/api/pgutil) to install a package, you can either configure the api key when [adding a source](/docs/proget/api/pgutil#sources) or by specifying it in the `upack install` command:

```bash
$ pgutil upack install --package=«package-name» --version=«package-version» --feed=«feed-name» --target=«install-location» --api-key=«api-key»
