Virtual packages are special packages that correspond to a feature that can be satisfied by more than one package. This Wiki page aims to describe when and how to use them correctly, and what are their implications.
Virtual packages, metapackages and package sets
Virtual packages, metapackages and package sets are similar concepts. However, they have a few important differences that make them fit for different use cases.
Virtual packages and metapackages are regular Funtoo packages (ebuilds) that install no files. Instead, they cause other packages to be installed by specifying them in their runtime dependencies. They can both be used in any context valid for regular packages. They can have multiple versions, slots and USE flags. They have to be located in an active repository, and once there they can be installed and uninstalled like regular packages.
Package sets are not packages but special atoms supported by Portage. Package sets can only specify other packages, either via a static list or dynamically (e.g. via running Python code that determines the package list). Package sets can't be versioned and don't have USE flags. Package sets can be used alongside packages in emerge commands and other package sets but they can't be referenced inside regular packages. Package sets can be installed into user's system, located in repositories or created by user in Portage configuration.
Virtual packages represent a commonly used feature that can be provided by multiple different providers. Virtuals provide a convenient way of specifying all possible alternatives without having to update multiple ebuilds.
Metapackages and package sets are used to represent lists of packages that user may want to install together. They provide a convenience for users, e.g. providing a shortcut to install all packages comprising a desktop environment.