drupal/core-recommended
Drupal core-recommended is a Composer metapackage that pins Drupal core and its recommended dependencies to compatible, secure versions, simplifying upgrades and helping teams maintain a stable Drupal installation with tested component versions.
Architecture fit
drupal/core-recommended is not a Laravel package — it is a Composer metapackage published by the Drupal project that installs drupal/core plus a curated set of Symfony components and third-party libraries, all pinned to the exact versions resolved in the Drupal release lockfile. It ships no application code, no service provider, no facade, and no config. It is a dependency-constraint artifact whose only job is to keep a Drupal site on a tested combination of transitive dependencies.
For a Laravel codebase, that means there is no in-process integration story. Installing it would attempt to pull drupal/core (a full CMS application with its own front controller, routing, entity system, and database schema) alongside Laravel's own symfony/* constraints. Laravel 10/11 pin symfony/* to the 6.x/7.x lines with their own patch floors; Drupal 10/11 pin the same components to different exact versions. Composer will either refuse to resolve or, worse, resolve to a combination neither project tests. drupal/core-recommended also replaces drupal/core, so any attempt to co-install or selectively override is explicitly unsupported by the maintainers.
The honest architectural read: this is a "choose one application framework per runtime" situation. The package is relevant to a Laravel/PHP team only if Drupal is being introduced as a separate service, not as a library.
Integration feasibility
symfony/console, symfony/http-kernel, symfony/routing, psr/*, and twig/twig. Even a successful resolve would produce an untested, unpatchable dependency graph.composer.json, exposed over JSON:API, GraphQL, or a custom REST module; Laravel consumes it as an HTTP dependency.drupal/core-recommended plus a minimal profile, JSON:API in core since Drupal 8, OAuth2 via simple_oauth. Laravel becomes the delivery/presentation layer.Technical risk
composer.lock + composer audit in CI.Key questions for the requester
Stack fit
Treat Drupal as a bounded context service, not a dependency. The correct topology is:
composer.json, composer.lock, PHP-FPM pool, and database.If the requirement is genuinely "one codebase," the correct recommendation is to not adopt this package and instead evaluate a Laravel-native content solution. Say so explicitly rather than attempting a co-install.
Migration path
Scenario A — introducing Drupal alongside Laravel (greenfield):
drupal/core-recommended + drupal/core-dev in that container's own Composer project. Do not merge into the Laravel composer.json.Scenario B — migrating off Drupal to Laravel:
/jsonapi index.Compatibility
Sequencing
composer audit in both, Drupal security advisory monitoring wired to on-call.Maintenance
Two release trains instead of one. Drupal core security releases land roughly monthly plus out-of-band criticals; each requires a composer update drupal/core-recommended --with-dependencies, a config export/import (drush cex/cim), and a regression pass. Laravel ships minor releases every six months and patches weekly. Budget roughly 0.2–0.3 FTE for Drupal upkeep alone on a small site, before content operations.
The metapackage's pinning cuts both ways: it makes upgrades deterministic and well-tested by the Drupal community, but it removes your ability to hot-patch a single transitive dependency. Accept that trade-off consciously.
Support
Internal Laravel talent will not transfer — Drupal's entity/field/plugin architecture, Twig theming, and config management system are a distinct skill set. External support is available (Acquia, Pantheon, Phase2, the Drupal Association), but it is a separate vendor relationship and a separate budget line. There is no "Laravel maintainer also covers Drupal" story.
Scaling
Drupal does not scale the same way a stateless Laravel API does. Expect to need:
jsonapi_extras and sparse fieldsets tuned.Each of these is an additional operational surface the Laravel side does not currently carry.
Failure modes
| Failure | Symptom | Mitigation |
|---|---|---|
| Composer conflict after a well-meaning merge | CI fails or, worse, resolves to untested versions | Enforce separate composer.json; add a CI guard rejecting drupal/* in the Laravel project |
| Drupal security patch lag | Known CVE in production | Subscribe to drupal.org security advisories; composer audit gate in Drupal CI; calendar reminder for monthly window |
| Cache invalidation drift | Stale content served by Laravel after editorial publish | Cache-tag propagation via webhook from Drupal hook_entity_update; short TTL as backstop |
| API contract drift on Drupal upgrade | Laravel client deserialization errors | Contract tests against a pinned schema; version the API surface |
| Auth token expiry / OAuth misconfiguration | 401s in production under load | Token refresh with jitter, alerting on 401 rate |
| Cross-service latency | p95 regression on content-heavy pages | Cache aggressively on the Laravel side; treat Drupal as a slow, authoritative source |
| PHP runtime divergence | One service pinned to an EOL PHP | Independent base images; track EOL dates per service |
Ramp-up
For a team that is strong in Laravel and new to Drupal: 6–10 weeks before a developer is independently productive in Drupal (module development, config management, Twig, Drush workflows). Theming and editorial UX add more. Estimate 2–3 sprints just to reach a credible spike, and treat the first production content type as a learning exercise with generous padding.
The recommendation to leadership is unambiguous: do not install this package into a Laravel application. Either adopt Drupal as a deliberately separate, separately-owned service with its own on-call and patch cadence, or do not adopt it at all. The cost is not the integration — the integration is straightforward HTTP — the cost is the second platform your team now operates.
How can I help you explore Laravel packages today?