Vendors

Metapackages and hidden dependencies

Bundle several of your own packages into one product. The buyer purchases the parent; everything the parent requires is pulled in automatically.

What a metapackage is

A metapackage is one of your packages whose composer.json requires other packages you also own. When a buyer purchases the metapackage, Composer pulls in the parent plus everything it requires. The buyer holds one licence on the parent; the platform recognises that licence on your child packages too, so Composer can fetch them without a separate purchase.

From the buyer's side this looks like buying one product. From your side you publish each helper as its own package and mark the helpers as hidden dependencies.

Public vs hidden dependency

Every package has a Visibility setting:

Public
The default. Listed in browse, has a public profile page, can be purchased on its own.
Hidden dependency
Not listed in browse. Cannot be purchased on its own. Reached only as a required dependency of one of your other packages. Use this for helper libraries that only exist to support a paid bundle.

You can flip a package between Public and Hidden dependency at any time from its pricing edit form. There is no need to re-tag a release.

Same-vendor only

The automatic entitlement walk stays inside your own vendor. If your composer.json requires another vendor's package, that stays an ordinary Composer dependency: the buyer fetches it from Packagist or wherever it lives, not from Packagento. Cross-vendor packages would need their own licence, and Packagento does not handle cross-vendor revenue sharing.

How to publish a bundle

  1. Publish each helper as a normal package. Connect the repository, tag a release, wait for it to ingest.
  2. On each helper's pricing edit form, set Visibility to Hidden dependency. The helper disappears from public browse and search immediately.
  3. Create the parent (the metapackage). Its composer.json requires each helper by composer name and version constraint, the same way any Composer package does.
  4. Tag a release of the parent. Once it ingests, the parent is ready to sell.

What the buyer sees

  • In browse and search, only the parent. Hidden dependencies do not appear anywhere a non-buyer can find them.
  • In their Composer install, composer require acme/bundle resolves the parent and pulls in every helper it requires.
  • In their account, one licence row for the parent. The helpers are not listed separately; the buyer does not need to know they exist.
  • On their invoice, one line for the parent. Helpers are not billed separately.

Pricing and payouts

The parent carries the price. Hidden dependencies are free at the row level; they ride on the parent's payment. Vendor payout, refunds, and subscription renewals all follow the parent.

If you want a helper to also be sellable on its own, flip its Visibility back to Public. It then shows in browse with its own price and can be bought directly while still being pulled in by the parent bundle. Both work at the same time.

Why hidden dependencies cannot be retired

Suspend, Reactivate, and Delete are disabled on hidden dependencies. The reason: if a buyer has already installed your parent package, their composer.lock points at specific versions of the children. Removing or suspending a child would break composer install for that buyer.

To retire a hidden dependency, first remove it from the parent's composer.json and tag a new parent version. Once no parent requires the child any more, you can flip the child back to Public and manage its lifecycle normally.

Troubleshooting

  • A helper did not get pulled in: check that the helper is your vendor. A require pointing at another vendor stays a normal Composer dependency, not a Packagento inclusion.
  • A helper still appears in browse: its Visibility is still Public. Open the helper's pricing edit form and set Visibility to Hidden dependency.
  • You added a require but the helper is not auto-linked: tag a new version of the parent so the new require is picked up.

See also