Adaptive Updates Info
Adaptive Updates Info reports which of your site's projects — Drupal core, modules and themes — have updates available, from the command line or from your own code, as readable text, JSON or YAML.
If you are new to Drupal: Drupal already checks drupal.org for new releases of everything you have installed, and shows the result on a page in the admin interface at Reports › Available updates. That page is built for a person sitting in front of a browser. The moment you want the same information anywhere else — in a nightly email, on a monitoring dashboard, in a check that stops a deployment while a security release is outstanding, or in a spreadsheet of versions across a dozen sites — there is nothing to call. You either read the page by eye or write code against Drupal's internals.
This module fills that gap. It adds two Drush commands that print the update status at your terminal or emit it as JSON or YAML for a script, and a documented service so your own module can ask the same question in PHP. It reads the update data Drupal already collects: it changes nothing, installs nothing, and stores nothing.
Features
- Two Drush commands.
drush aui:updatesreports every project that needs attention;drush aui:securityreports only projects with a security release and exits with a non-zero status when it finds one, so it can fail a build or block a deploy. - Output for people and for machines.
--format=table(the default) is written for the terminal;--format=jsonand--format=yamlemit the full report for scripts, dashboards and monitoring tools. - Most urgent first. Security releases come first, then revoked releases, then unsupported ones, then ordinary updates, alphabetically within each group — so what matters is always at the top of the output.
- Detail the admin page does not give you in a usable form. For each project: installed and recommended versions, release date, release notes link, release type, core compatibility, and the modules the project covers, so a project name can be traced back to what is actually installed.
- A site-wide summary. Counts of security, revoked, unsupported, pending and unknown projects, plus the timestamp of the last check, in every machine readable response.
- A full inventory on demand.
--alladds the projects that are already up to date, turning the report into a complete version inventory of the site. - Fast mode.
--skip-refreshreports the data Drupal has already stored, with no network requests, for checks that run often. - A reusable service.
adaptive_updates_info.updates_infodoes all of the work behind an interface, so a custom module, a REST resource, a cron hook or your own Drush command can produce the same report without duplicating any of it. - Read-only and quiet. No configuration, no user interface, no permissions, no database writes, and no data sent anywhere beyond the update check Drupal core already performs.
When would you use it?
- A nightly job that posts pending updates to Slack, Teams or email.
- A CI or deployment pipeline that refuses to ship while a security release is outstanding.
- An agency or hosting dashboard that tracks update status across many sites from one place.
- Maintenance reporting: a per-site record of exactly which versions were installed at the time of a release.
- Any custom module that needs to know whether the site is up to date, without re-implementing the logic.
Post-Installation
There is nothing to configure. The module has no settings page, no permissions, no content types and no blocks; enabling it simply makes the commands and the service available. Drupal core's Update Status module is installed with it automatically.
Check that the commands are registered:
drush listYou should see an aui: section listing aui:security and aui:updates. If it is not there, rebuild the caches with drush cr. Under DDEV or Lando, prefix the commands as usual (ddev drush aui:updates).
Reporting available updates
drush aui:updatesThe command refreshes the release data from drupal.org, then reports only the projects that need attention — a security release, a revoked release, an unsupported release, or simply a newer release available. Projects that are up to date are left out, so a healthy site prints a single line:
[OK] All projects are up to date.Otherwise you get a section per project, worst first, followed by a summary of the whole site:
Entity API (module) ------------------- Status: SECURITY UPDATE Installed: 8.x-1.6 Recommended: 8.x-1.8 (2026-08-26 https://www.drupal.org/project/entity/releases/8.x-1.8) Includes: Entity Session Entity (module) ----------------------- Status: NOT SUPPORTED Installed: 8.x-1.0-beta2+1-dev Recommended: 2.0.1 (2024-01-23 https://www.drupal.org/project/session_entity/releases/2.0.1) Includes: Session Entity [ERROR] 1 security update(s) available! ! [WARNING] 1 unsupported release(s) installed. ! [WARNING] 14 update(s) available.
aui-updates works as an alias, and drush aui:updates --help lists everything below at the terminal.
Options
--all— also report the projects that are already up to date. They are listed last, after everything that needs work. The security, revoked, unsupported and pending counters in the summary are the same either way, because an up-to-date project never adds to them; what changes istotal, which becomes the number of installed projects rather than the number needing attention. Use it when you want a full inventory rather than a to-do list. On a large site this produces a long report, so it pairs best with--format=jsonor--format=yaml. (aui:updatesonly.)--format=table|json|yaml— how the report is rendered; defaults totable. Any other value is rejected with an error listing the supported formats.--skip-refresh— report the release data Drupal has already stored instead of fetching fresh data. It returns immediately and makes no network requests, at the cost of being as old as the last check; thelast_checkedvalue in the JSON and YAML output tells you how old that is. Use it for checks that run often, and leave it off when the answer has to be current, such as before a deployment.
Output formats
Table is the default and is meant for a person: a section per project, then a colour-coded summary, as shown above.
JSON gives the complete report, pretty-printed:
drush aui:updates --format=json drush aui:updates --all --format=json
{ "projects": [ { "name": "entity", "title": "Entity API", "type": "module", "installed": "8.x-1.6", "installed_release": [], "recommended": "8.x-1.8", "recommended_release": { "version": "8.x-1.8", "release_link": "https://www.drupal.org/project/entity/releases/8.x-1.8", "date": "2026-08-26", "core_compatibility": "^10.1 || ^11", "core_compatibility_message": "Requires Drupal core: 11.3.14 to 11.4.6", "release_type": ["Security update"] }, "also_available": [], "includes": ["Entity"], "status": "SECURITY UPDATE", "status_code": 1, "has_update": true, "is_security_update": true } ], "summary": { "security": 1, "updates": 14, "revoked": 0, "not_supported": 1, "unknown": 0, "total": 16 }, "last_checked": "2026-09-04T14:01:25+00:00" }
Progress notices, warnings and errors are written to stderr, so stdout stays valid JSON and can be piped straight into another tool:
# The projects with a security release, as a list of names. drush aui:updates --format=json | jq -r '.projects[] | select(.is_security_update) | .name' # How many updates are pending. drush aui:updates --format=json | jq '.summary.updates' # A file for a dashboard to pick up. drush aui:updates --all --format=json > /var/www/reports/updates.json
YAML carries exactly the same structure, which is easier to read by eye when you still want every field:
drush aui:updates --format=yamlA release details value holds version and, when drupal.org provides them, release_link, date, core_compatibility, core_compatibility_message and release_type. It is empty when drupal.org no longer lists that release, which is common for the installed version of an older project.
Security updates only, and failing a build
drush aui:security drush aui:security --format=json
aui:security lists only the projects with a security release available and exits with a non-zero status when there is one, which is what makes it useful in a pipeline:
drush aui:security --skip-refresh --format=json > security.json \ || echo 'Security updates are pending.'
It takes the same --skip-refresh and --format options, and aui-security is an alias. Its summary is calculated before the security filter is applied, so the other pending updates stay visible even though they are not listed.
Exit codes: 0 means the report was produced (and, for aui:security, that nothing was found). 1 means aui:security found at least one security update, or that an unsupported --format value was given. aui:updates returns 0 whatever the report contains, so use aui:security — or the summary in the JSON output — to fail a build.
Status values
SECURITY UPDATE(code 1) — a security release is available.REVOKED(2) — the installed release has been revoked.NOT SUPPORTED(3) — the installed release is no longer supported.Update available(4) — a newer release is available.Up to date(5) — the installed version is the recommended one.Not checked(-1),Unknown(-2),Not fetched(-3),Fetch pending(-4) — no usable update data for that project yet.
The labels are deliberately not translated, so that scripts can rely on them; status_code is there for machine comparison.
Using the service in your own code
/** @var \Drupal\adaptive_updates_info\UpdatesInfoInterface $updates_info */ $updates_info = \Drupal::service('adaptive_updates_info.updates_info'); // The projects that need attention, using the stored release data. $projects = $updates_info->getProjects(); // Every project, after refreshing the release data, plus the summary. $report = $updates_info->getReport(TRUE, TRUE); // Just refresh the stored data, for example from a cron hook. $updates_info->refresh();
In your own services, type hint \Drupal\adaptive_updates_info\UpdatesInfoInterface and let autowiring inject it. Both getProjects() and getReport() take $include_current (the equivalent of --all) and $refresh (the opposite of --skip-refresh, and off by default). Refreshing performs network requests to the update servers, so leave it off when the stored data is good enough.
Things worth knowing
- The report is only as good as the update data Drupal can fetch, so the site needs outbound HTTPS access to the update servers unless you always pass
--skip-refresh. - Refreshing contacts the update servers for every project. On a large site the command can take a while; that is why
--skip-refreshexists. - Everything is per site, so on a multisite installation run the commands with the usual Drush site selector (
drush @site aui:updatesor-l). - The module reports updates; it never applies them. See the recommended modules below for that.
Additional Requirements
- Drupal 10.3 or Drupal 11.
- PHP 8.1 or newer.
- Drupal core's Update Status (
update) module. It is a dependency, so it is installed automatically. - Drush 12 or newer for the
aui:updatesandaui:securitycommands. The commands are attribute based and live insrc/Drush/Commands, which Drush discovers from version 12 on; Drush 11 and earlier will not see them. The service itself has no Drush dependency and works without it. - Outbound HTTPS access to the update servers (
updates.drupal.orgby default), unless the commands are always run with--skip-refresh.
No third-party libraries, no API keys and no external services are involved.
Recommended modules/libraries
- Automatic Updates (and core's Package Manager) — this module tells you what needs updating; those apply the update.
- Drupal core's Update Status settings at
/admin/reports/updates/settings— turn on email notifications so a person is told as well as a script. - Upgrade Status — for the different question of whether your code is ready for the next major version of Drupal.
Similar projects
- Drupal core's Update Status report (Reports › Available updates) uses the same underlying data, and is the right tool when a person is looking at the site in a browser. It has no command line or programmatic equivalent, which is exactly what this module adds.
drush pm:securitywas removed in Drush 13 and now points users atcomposer audit, so there is no longer a built-in Drush command reporting Drupal project update status.composer auditandcomposer outdatedwork at the Composer package level.composer auditreports security advisories only;composer outdatedknows nothing about Drupal core compatibility, release types or projects that are not managed by Composer. This module reports what Drupal itself thinks about every installed project, including whether a release is revoked or unsupported.- Site Audit runs a broad best-practice review of a site. Its scope is much wider; this module does one thing and gives you the structured output to build on.
Supporting this Module
This module is maintained by Adaptive. Issues, patches and merge requests are very welcome in the issue queue — bug reports with the output of drush aui:updates --format=json are especially useful.
Community Documentation
The README in the repository documents every command, option, output format and report field in full.
Depends on
Dependencies of the latest stable release
- update Drupal core
Required by
Tracked projects that depend on this one
No tracked projects depend on this one yet.
Activity
Releases
| Version | Type | Core | Notes | Release date | |
|---|---|---|---|---|---|
| 1.0.0 | Stable | 10–11 | Reports the update status of core, modules and themes as a reusable service and as Drush commands, in table, JSON or YAML, so it can feed a dashboard, a cron job or a CI pipeline. | Sep 4, 2026 |