Open-source project
freebsd/freebsd-ports avatar
freebsd/freebsd-ports

freebsd-ports: a mirror of the FreeBSD Ports Collection

FreeBSD ports tree (read-only mirror)

1,220 stars883 forksMakefileNOASSERTION

At a glance

What is it?
This repository is a read-only mirror of the FreeBSD Ports Collection, the tree of per-package build recipes that FreeBSD has used for decades, organised into categories and searchable with make search. It is not a package manager you run from a checkout, and the README spends as much space on disk hygiene as on installation.
Who is it for?
Adopt freebsd-ports as a reference, as a source of build recipes you can read, and as the upstream you track if you maintain ports, and use it with the ports(7) manual page and the Handbook rather than as something to build by hand. Do not try to use this mirror as a package manager for a machine, since it is explicitly a read-only mirror and the tree is meant to be used from a FreeBSD checkout with the ports infrastructure around it.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Makefile, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A mirror, and the three places the real documentation lives

The README opens by saying what this is: the FreeBSD Ports Collection. The repository description adds the important qualifier, that it is a read-only mirror.

That word mirror changes how you should approach the tree. It is not where FreeBSD developers commit, and it is not a package manager you point at your machine. It is a copy of the collection, useful for reading, for searching and for tracking changes, while the real workflow happens elsewhere.

The README is careful to route you to the proper documentation rather than to restate it. For an easy to use web-based interface it points at ports.FreeBSD.org. For general information it points at the ports section of the FreeBSD Handbook for the latest official version, and at the ports(7) manual page, which is the reference for how to use ports and packages. For contributing it points at the Porter's Handbook, which is the document a porter actually works from.

So the repository is deliberately thin on instructions. Its own value is the tree itself, and the search facility, which is the one thing the README shows you how to do directly.

Searching the tree without a web interface

The one command the README documents in full is the search. From inside the ports tree, you can find a port by name:

shell
make search name="<name>"

or by keyword:

shell
make search key="<keyword>"

and both generate a list of all the ports that match. The keyword form is the one that matters in practice, because a package is often called something different from the thing you want, and searching by a keyword finds the port whose description mentions it.

Wildcards work too, and the README gives the form:

shell
make search name="gtk*"

This is a plain make target inside the tree, which is a small reminder of how the collection is built. Everything is a Makefile, and the search is implemented as a target that walks the categories and queries the index. That is why the search is documented as running in the ports directory rather than as a separate command.

The web interface at ports.FreeBSD.org is the friendlier path for a one-off lookup, and the README mentions it first, but the make search target is the one that works in a checkout, in a script, or over ssh on a machine where you do not want to open a browser.

The category tree, and the top-level Makefile that drives it

The repository is a tree of categories, and the top-level Makefile lists every one of them as a SUBDIR, from accessibility and arabic through archivers, astro, audio, benchmarks, biology, cad, chinese, comms, converters, databases, deskutils, devel, dns, editors, emulators, filesystems, finance, ftp, games, graphics, the language collections, mail, math, misc, multimedia, the net variants, news, the ports management directory, print, russian, science, security, shells, sysutils, textproc, ukrainian, vietnamese, www and the x11 family.

The mechanism at the end of that list is the important line:

make
PORTSTOP=	yes

.include <bsd.port.subdir.mk>

The top-level Makefile is not doing the work itself, it is delegating. The bsd.port.subdir.mk include is what turns each SUBDIR into a build, and PORTSTOP tells the recursion to stop at this level rather than continuing to some parent collection.

The rest of the root is the infrastructure of a ports tree rather than of a package. There is Mk/ for the shared makefiles, Templates/ for the port templates, Tools/ for the helper scripts, Keywords/ for the keyword database, plus the metadata files a collection needs: GIDs, UIDs, MOVED for ports that have changed name, CHANGES and UPDATING for the user-visible history, .mailmap, .arcconfig for the commit tooling, COPYRIGHT for the licensing, and .hooks/ for the commit hooks.

CONTRIBUTING.md and a README sit alongside all of that, and the whole thing is Makefile by primary language, which tells you how much of the ports system is expressed in make.

The package index and the compression formats it accepts

The Makefile also builds the index, which is what makes a search fast and what the binary packages are generated from. The target is simple:

make
index: 	${INDEXDIR}/${INDEXFILE}

and the compression format is a variable that defaults to xz, with an explicit check that it is one of three values:

make
INDEX_COMPRESSION_FORMAT?=	xz

.if ${INDEX_COMPRESSION_FORMAT} != xz && \
	${INDEX_COMPRESSION_FORMAT} != bz2 && ${INDEX_COMPRESSION_FORMAT} != zst
.error "Invalid compression format: ${INDEX_COMPRESSION_FORMAT}, expecting xz, bz2 or zst"
.endif

The fetchindex target then downloads the compressed index and decompresses it with bsdcat, chmods it to be world readable, and removes the compressed copy. A collection index is a large machine-generated file, and the decision to support three compression formats is a practical one about what the download servers and the clients can handle.

The other half of the index story is the package format itself, and that is the part this repository does not contain. The tree holds the recipes; the built packages are produced by the ports infrastructure and the binary package service, and the ports(7) manual page is where the difference between the two ways of installing is documented.

The distfiles problem, and why make clean is in the workflow

The last part of the README is a warning about disk space, and it is more emphatic than the rest of the document. The note says the tree will grow significantly in size during normal usage, because the distribution tar files accumulate in /usr/ports/distfiles, and because the individual ports use up a lot of space in their work subdirectories unless you remember to make clean after you are done building a given port. It adds that /usr/ports/distfiles can also be periodically cleaned without ill-effect.

That is an accurate description of how the ports system behaves, and it is a real operational fact that newcomers to FreeBSD packaging meet as a surprise. The distfiles directory is a cache of everything downloaded, which is what makes a rebuild fast and what makes the tree grow without bound, and the work directories hold the unpacked and compiled output of each port you build.

The distinction between the two matters. Cleaning the work directories is per-port housekeeping and the make clean target handles it. Cleaning distfiles is a cache eviction, and the README says it can be done periodically with no ill-effect, which is the right way to think about it: the cache is an optimisation, not state.

For anyone reading this mirror rather than building from it, none of this applies, since no distfile is ever downloaded into a git checkout. It matters the moment you copy the tree onto a machine and start using it.

Where the ports tree is the wrong tool

The first wrong-tool case is installing software on a machine. This is a mirror of recipes, and a mirror is not an install path. A FreeBSD system installs ports and packages through the ports(7) tooling, with the ports tree present on the system and the packages served by the binary package service. Pointing pkg at a git checkout is not a documented workflow, and the README points at the Handbook and the manual page rather than at anything in this repository.

The second is a multi-platform or non-FreeBSD environment. A port is a Makefile that encodes the assumptions of one operating system, with patches, dependencies and options specific to FreeBSD. The result is portable in the sense that a port can sometimes be reused elsewhere, and it is not a cross-platform build system. On Linux, the comparable workflow is a distribution package manager, and the difference in the two models is exactly what the MOVED, Keywords/ and Templates/ machinery exists to manage in the FreeBSD case.

The third is expecting a per-package release history from this repository. There are no GitHub releases, and the per-port version history lives inside the collection and in the UPDATING and CHANGES files, so a reader looking for the changelog of a single port in the repository's own release list will not find one.

The COPYRIGHT file, the mirror status and a push days ago

The licensing is the unusual part. The project licence is recorded as Other, a custom licence GitHub cannot classify, and the answer is the COPYRIGHT file in the root of the tree. For a collection that vendors patches and metadata for many packages, the licensing is a per-port matter with a collection-wide policy on top, and it is not reducible to a single standard identifier. Read the file rather than assuming a licence from the repository metadata.

The mirror status is visible in the repository description, and the default branch is main. The repository is not archived, and the last push was on 2026-10-19, a day before this review, so the mirror is being refreshed on the order of days rather than months, which is what you would expect of something that tracks an upstream tree.

There are no GitHub releases, and the repository does not need them. A ports tree is not versioned as a product, it is a moving body of recipes with its own per-port versioning, and the user-visible history is in the CHANGES and UPDATING files rather than in release tags. For a reader, the practical consequence is that to find out what changed in a given port you read the port directory and the collection's own files, not a release note.

Editorial conclusion

Adopt freebsd-ports as a reference, as a source of build recipes you can read, and as the upstream you track if you maintain ports, and use it with the ports(7) manual page and the Handbook rather than as something to build by hand. Do not try to use this mirror as a package manager for a machine, since it is explicitly a read-only mirror and the tree is meant to be used from a FreeBSD checkout with the ports infrastructure around it. Before you clone it, read the note about the tree growing in size, plan the disk space for distfiles, and remember that make clean is part of the workflow, and check the COPYRIGHT file in the root, since the licence is the custom one recorded there rather than a standard OSI identifier.

Frequently asked questions

How do I search for a port in the FreeBSD Ports Collection?

From inside the ports tree, run make search name="<name>" to match a port by name or make search key="<keyword>" to search descriptions, and both generate a list of matching ports. Wildcards are supported, for example make search name="gtk*".

What is the difference between this repository and the FreeBSD ports tree?

The repository is a read-only mirror of the FreeBSD Ports Collection. The web interface at ports.FreeBSD.org, the ports section of the FreeBSD Handbook and the ports(7) manual page are the places the README points you to for actually using ports and packages.

How do I contribute a port to FreeBSD?

The README points to the Porter's Handbook, available in the FreeBSD Handbook documentation, for the contribution process. The repository also carries a CONTRIBUTING.md file and the shared Templates/ and Tools/ directories that the porting process relies on.

Why does building ports need so much disk space?

The README warns that the tree grows significantly during normal use, because distribution tar files accumulate in /usr/ports/distfiles and each port uses space in its work subdirectory unless you run make clean afterwards. The distfiles directory can also be cleaned periodically without ill-effect.

What licence does the FreeBSD ports tree use?

The project licence is recorded as a custom licence that GitHub cannot classify, and the terms are in the COPYRIGHT file at the root of the repository. The most recent listed activity is a push on 2026-10-19.

Official sources

  1. freebsd/freebsd-ports on GitHub
  2. Issues
  3. Project website
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/freebsd-freebsd-ports.svg)](https://hysenlabs.com/projects/freebsd-freebsd-ports)

Was this useful?