Learn OpenBSD - Package Management: pkg_add & Packages
Episode 4 of 23

Learn OpenBSD - Package Management: pkg_add & Packages

Managing third-party software on OpenBSD with pkg_add, pkg_info, pkg_delete, and pkg_check, understanding the PKG_PATH variable, and getting to know the source-based ports system and the parallel build tool dpb along with the binary versus source tradeoff.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Introduction

In episode 3 you installed pure OpenBSD — a base system without additional applications. Now it's time to extend the system with third-party software. This is one of OpenBSD's distinctive differences that most often surprises newcomers: there's no apt update, no yum. What exists is pkg_add and the world of ports.

Why is it different? Because OpenBSD sharply separates the base system from packages, and every package is built from ports — an audited collection of build recipes. This model gives you full control over what enters the system, in the spirit of secure by default.

pkg_add: Installing Packages

Installing a package is done with pkg_add. Its syntax is simple:

Installing packages
pkg_add rsync
pkg_add nginx
pkg_add -U package_name

Some useful options:

  • pkg_add -v displays detailed progress.
  • pkg_add -U allows updating (upgrading) a package.
  • pkg_add -D uses non-interactive default answers.

Packages are installed into /usr/local and recorded in the package database. Unlike the base system, everything that comes from pkg_add lives in that directory, so it never overwrites base system utilities.

The PKG_PATH Variable

Without PKG_PATH, pkg_add uses the default repo matching the OS release version. To install from a specific repository or for a non-default version, set PKG_PATH:

Specifying the package repository
export PKG_PATH=https://cdn.openbsd.org/pub/OpenBSD/7.4/packages/amd64/
pkg_add rsync

Once PKG_PATH is set, pkg_add can follow dependencies automatically. A correct PKG_PATH value follows the pattern .../pub/OpenBSD/<version>/packages/<arch>/.

pkg_info: Inspecting Packages

To see installed packages and their details:

Displaying package information
pkg_info
pkg_info -Q nginx
pkg_info -e nginx
  • pkg_info without arguments: lists all installed packages.
  • pkg_info -Q nginx: searches for available packages (query).
  • pkg_info -e nginx: checks whether a package is already installed.

Full information such as description, dependencies, and files owned by a package can be seen with pkg_info -f package_name or pkg_info -L package_name.

pkg_delete: Removing Packages

Removal is done with pkg_delete, and it can also remove unused dependencies at the same time:

Removing packages
pkg_delete nginx
pkg_delete -a
pkg_delete -x 'nginx-*'

pkg_delete -a cleans up packages no longer needed by other dependencies. The -x option removes based on a wildcard expression.

pkg_check: Ensuring System Health

OpenBSD provides pkg_check to verify the consistency of installed packages — for example, making sure all dependencies still exist and no files are missing:

Checking package health
pkg_check
pkg_check -a

Run pkg_check periodically, especially after updates or removals, to detect broken packages early.

Info

Updating all packages on OpenBSD is not done with a single "distro upgrade" command. The practice is to upgrade the base system first (via sysupgrade), then update the packages with pkg_add -u against the new release repository.

Ports: Building from Source

The /usr/ports Structure

When a binary package isn't available or you need special build options, use ports. The ports tree can be fetched via git or a tarball, and placed in /usr/ports:

Fetching the ports tree
cd /usr
git clone https://github.com/openbsd/ports.git

Each port is a directory containing a Makefile, distinfo, and pkg/. For example, the port for rsync lives in net/rsync.

make install

To build and install a port:

Building a port from source
cd /usr/ports/net/rsync
make install
make clean

This process downloads the source, verifies the checksum from distinfo, builds, then packages it as a package installed with pkg_add. The end result is the same as a binary package — the difference is that you did the compiling.

dpb: Parallel Builds

Building dozens of ports one by one is slow. dpb (distributed/parallel build) automates building many ports at once, taking advantage of multiple cores or multiple machines:

Running dpb
/usr/ports/infrastructure/bin/dpb -B /usr/ports/pkgdir net/rsync net/nginx

dpb handles dependency ordering, builds in parallel, and produces packages in pkgdir. It's an essential tool for anyone maintaining their own package repository.

Tradeoff: Binary vs Source

AspectBinary package (pkg_add)Ports (make install)
SpeedVery fastSlow (compiling)
Build optionsLimited to defaultsCustomizable via Makefile
MaintenanceLowToolchain upkeep needed
Best forProduction and most usersSpecial needs, developers

For almost all production cases, binary packages are the right choice: fast, consistent, and already tested. Ports become the choice when you need specific build flags or when running your own build infrastructure.

Closing

In episode 4 you mastered OpenBSD package management: installing with pkg_add, inspecting with pkg_info, removing with pkg_delete, ensuring health with pkg_check, understanding PKG_PATH, and getting to know the world of ports and dpb along with the binary versus source tradeoff.

Key takeaways:

  • pkg_add, pkg_info, pkg_delete, and pkg_check are the package lifecycle.
  • Packages live in /usr/local and never interfere with the base system.
  • PKG_PATH determines the repository; updates are done via pkg_add -u after a base system upgrade.
  • Binary packages for production, ports for special build needs.

In the next episode, episode 5, we'll manage users, groups, and doas — creating accounts with useradd, mapping groups in /etc/group, and replacing sudo with the simpler and more secure doas via /etc/doas.conf. Your system will start to be "inhabited" now!