How to declare core requirements in composer.json? If a module depends on a particular minor release of Drupal (eg 8.4.*), the best practice is to declare this in info.yml: This blocks installation of the module if core is too old.

However, this just blocks installation, and doesn't help at all with falling back to a compatible version. We can make this much easier by also declaring the compatibility in composer.json.

Requiring drupal/core in the composer.json of a module seems like a major change, though. For one thing, it means that your local dev environment pulls in core as well as all its dependencies (about 40 packages), and not their default locked versions either, but the latest supported ones (same effect as running composer update in a core checkout). For another, it will cause problems for all environments that use composer for contrib only.

I think "conflict": {"drupal/core": "&lt;8.4"} might be a low-impact solution here.

Is there an accepted best practice for this already?
On further experimentation, it appears that it is unnecessary to add this to the composer.json file. It is enough to add drupal:system (&gt;=8.3) to the info.yml requirements. This seems to be automatically interpreted by the drupal.org package repository.

Even when the composer.json file does not specify any dependencies, composer show drupal/MODULE will show that it requires ^8.3, and it will be impossible to install the composer package on an 8.2 site.