In the GNU world, there's a pretty vague boundary between what is the operating system and what is a third‐party package. Arguably, everything is a third‐party package, although there are some operating systems such as Debian that have notions about ‘essential’ packages that may not be uninstalled.
On the BSDs, this distinction is much more marked, and the BSDs are much more like Windows NT (where third‐party applications have for many years had their own directories for program files, program data, and local app data) and the Unices of yore. However, BSD never adopted one of the conventions that the Unices of yore, that were in the AT&T System 5 world, adopted. This convention can even be found in the Linux Filesystem Hierarchy Standard, which took it from the System 5 world. The BSD world differs from Linux in this respect.
/opt convention.
The Unices of yore defined /opt as the place for third‐party applications.
Unfortunately, their definition only extended to corporations that were publicly traded on a United States of America stock exchange.
This is problematic for an operating system where tens of thousands of actual and potential applications are made by one or a handful of people who work on them voluntarily in their spare time in countries far distant from the U.S.A..
It's even problematic from a corporate‐centric U.S.A.‐centric world view.
The ‘SUNW’ in /opt/SUNWspro and /opt/SUNWadm was Sun Microsystems's stock ticker code on the U.S.A. New York NASDAQ.
It has been the NASDAQ code for a completely different company for many years, now.
Per the ill‐thought rules, in the 2020s a solar energy company from Utah U.S.A. officially has control over Oracle Developer Studio and the Sun AdminSuite.
But the corporatism embedded into the whole idea is a more overarching problem.
The reason that /opt was invented in the first place, was the idea that only the operating system had files under /usr.
This was why AT&T Unix in the System 5 Era moved home directories out of /usr/home (a placement that FreeBSD retained until the 2010s) to /home and third‐party packages out of the likes of /usr/lbin and /usr/local to /opt.
The BSDs don't do that, though.
They never had a ‘/usr merge’.
The operating system is in the root directory, in /rescue, in /usr, in /boot and several other places.
/usr convention.
Instead, the BSDs take a leaf out of the old Unix book, where the PATH environment variable controlled operating system personality.
On operating systems like SunOS/Solaris, the ‘BSD’ personality was invoked by putting /usr/ucb/bin into the value of PATH.
The /usr/ucb tree was where all of the BSD‐like versions of standard utilities were kept.
There was a /usr/xpg4 tree for X/Open Portability Guide version 4 conformant utilities, and a /usr/xpg6 tree for X/Open Portability Guide version 6 conformant utilities.
Turnabout being fair play, this is what the BSDs do to third‐party applications.
Such applications live in an entire subtree rooted at /usr/pkg (on NetBSD) or /usr/local (on OpenBSD or FreeBSD).
These are proper hierarchies in their own rights, with bin, etc, lib, man and suchlike subdirectories of their own.
Their various subdirectories are listed in environment variables such as PATH, MANPATH, and suchlike.
Notably, these subtrees's etc subdirectories is where a lot of files live instead of under /etc.
For examples:
Expect the sudo configuration file to be /usr/local/etc/sudo.conf or /usr/pkg/etc/sudo.conf.
Any package that has a Mewburn rc file has it placed in /usr/local/etc/rc.d/ or /usr/pkg/etc/rc.d/, which Mewburn rc knows to check for scripts in addition to checking /etc/rc.d/.
The NetBSD version is the superior one, as it allows for a distinction between third‐party applications that have been compiled by someone else and wrapped up in a nice neat package for a packaging tool to install self‐contained under /usr/pkg, and truly ‘locally built’ stuff that goes under /usr/local.
One interesting thing that this addresses is the proliferation of ‘bin’ directories that have to be listed in the value of the PATH and MANPATH environment variables in the /opt system.
/package shares this problem and that is one of the reasons that Daniel J. Bernstein invented /command alongside it.
Solaris addressed the MANPATH problem by making the man command derive its search path from the PATH environment variable, replacing bin subdirectories with man subdirectories and special‐casing the operating system's manuals under /usr.
The BSD system does not have this proliferation, no matter how many packages are installed.
All packages have their commands, libraries, headers, manuals, and miscellaneous files under /usr/local or /usr/pkg, all mashed together, so PATH only has to include /usr/local/bin and /usr/pkg/bin.
Of course, this in turn means that the packaging system has to track installed files and check package manifests for potential conflicts, something which was never an issue with /opt and the somewhat simpler AT&T Unix package management tools.
There is actually a middle ground.
One can have /package or /opt (or even pkgsrc or a BSD ports tree) to minimize name clashes, and manage /usr/pkg/{bin,man,lib}/ as a symbolic link farm, just like Daniel J. Bernstein's /command, except that there's no ‘officially registered name’ system, but rather the system administrator's choice as to what (say) /usr/local/bin/zsh symbolically links to.
The BSD world has not realized this, yet. ☺
© Copyright 2026
Jonathan de Boyne Pollard.
"Moral" rights asserted.
Permission is hereby granted to copy and to distribute this web page in its original, unmodified form as long as its last modification datestamp is preserved.