Currently Available: Need a skilled Software Developer for your next project?
Categories
Laravel

Adding a Compatibility Table to Your Package README

If you maintain a PHP package, a compatibility table helps users compare release lines with the PHP and framework versions they use. Composer uses the requirements in requirements declared in composer.json to decide which packages it can install. The file contains the package’s machine-readable metadata. The README table gives people a quick summary, but it does not affect Composer’s decisions.

Keep each table row tied to the metadata for a specific release line, and label tested combinations separately from declared requirements. That distinction helps users understand what Composer will accept and what your tests have actually exercised.

Choose columns that answer users’ questions

For each maintained release line, show the requirements that matter to people deciding whether to install it.

Package release line PHP requirement Framework or integration requirement Required extensions Tested combinations
Each maintained line Copy the constraint from that release’s composer.json Include relevant dependency constraints from that release’s metadata List runtime extensions declared as requirements Name only environments covered by CI or other explicit verification

Composer lets package maintainers declare PHP, extension, and dependency requirements in the require section of composer.json. An extension requirement identifies a PHP feature the package needs at runtime. Include required extensions in Composer metadata as well as in the table; otherwise, Composer might install the package even when the running PHP environment lacks an extension the code needs.

Choose columns based on what users need to check. A package with no special extension requirements does not need an extensions column. A package that integrates with a framework should show that framework’s package constraint when it affects installation or use. Existing README tables illustrate different levels of detail: Okipa’s Laravel package lists several compatibility dimensions, while Composer’s requirements provide the machine-readable constraints behind such claims.

Keep requirements and test results distinct. A Composer constraint tells Composer which versions it may accept during dependency resolution. A continuous integration (CI) matrix records the environments where automated jobs ran the package’s tests. A broad PHP constraint does not establish that tests ran on every PHP version within that range.

Keep rows tied to released versions

When a requirement changes, update composer.json and the README row for the affected release line together. For older lines, use the metadata attached to the relevant release or tag. The current branch’s composer.json might describe newer requirements than a previously released version.

Use CI results to support any “tested” claim. A CI matrix lets maintainers run tests in selected environments. The setup-php project documentation describes this approach. Composer also recommends that library maintainers run tests with normal dependency resolution and with --prefer-lowest, which checks the lowest versions allowed by declared constraints. These jobs show that the package was tested in the environments they cover. They do not show that it was tested in every possible combination allowed by a constraint. See Composer’s guidance for testing libraries.

When you prepare a release, run composer validate to check the Composer metadata and, if the package has a composer.lock file, whether it is up to date. That command does not check README content, so it cannot catch a disagreement between the table and package metadata. For a table that changes frequently, add a separate script or generate the table from versioned metadata. Composer does not provide a built-in README synchronization check.

Keep the README consistent with Composer

Treat composer.json as the source for installation requirements. Copy each constraint into the corresponding README row, or describe it in wording that preserves the same range. If the table and metadata disagree, Composer follows the metadata.

Keep development tools out of consumer-facing requirements. Composer uses require-dev for packages needed to develop or test the package, rather than dependencies consumers must install. Composer documents require-dev separately in its schema reference.

Do not use composer.lock as the package’s public compatibility range. For a library, the lock file helps maintainers reproduce their development and CI environments. Consumers use the library’s declared constraints to resolve dependency versions. Likewise, config.platform lets Composer resolve dependencies as if a specified PHP or extension version were present, but it does not change the actual runtime. When that distinction matters, check the real environment with composer check-platform-reqs. Composer documents the behavior of config.platform.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *