WordPress gestionado con Composer en un párrafo
WP Packages es el segundo repositorio Composer open source para el directorio de WordPress.org. WPackagist hace el mismo trabajo desde 2013. La historia interesante no es “qué mirror gana”, sino el hecho de que en 2026 cualquier agencia WordPress española que ejecute CI/CD, despliegues multientorno, o incluso un solo proyecto Bedrock, gana tratando los plugins como dependencias Composer. El botón “Instalar” del dashboard no sobrevive al contacto con un artefacto de despliegue.
El resto de esta guía recorre el stack Roots (Bedrock, Sage, Trellis), las concesiones entre WP Packages y WPackagist, el problema de los plugins premium del que nadie quiere hablar, y los modos de fallo que tropiezan a equipos que abandonan el flujo de instalación por dashboard.
Lo que Roots realmente entregó
En marzo de 2026 el equipo de Roots (Scott Walkinshaw, Ben Word y colaboradores) lanzó WP Packages en wp-packages.org. Replica cada plugin y tema gratuito del directorio WordPress.org y los sirve como repositorio Composer JSON.
El lanzamiento no fue suave. El proyecto salió un martes como “WP Composer”. Para el viernes Nils Adermann (cocreador de Composer, también colaborador de la especificación SemVer) había contactado para señalar que Composer es una marca registrada del proyecto Composer. Roots renombró durante el fin de semana, mantuvo las URLs wp-composer.org existentes respondiendo con 410 más aviso de descontinuación, y empujó una actualización de plantilla Bedrock para que los nuevos proyectos apuntaran al host renombrado. Este es el tipo de incidente que en un proveedor corporativo habría llevado seis semanas de revisión jurídica. Los proyectos open source lo arreglan antes de que aterrice el post mortem en el blog.
El composer.json que reemplaza tu dashboard
{
"repositories": [
{
"type": "composer",
"url": "https://wp-packages.org"
}
],
"require": {
"php": ">=8.2",
"wp-packages/advanced-custom-fields": "^6.3",
"wp-packages/woocommerce": "^9.4",
"wp-packages/wordpress-seo": "^23.0"
}
}
composer install resuelve entonces un árbol, escribe composer.lock y descarga ZIPs en web/app/plugins/ (layout Bedrock) o wp-content/plugins/ (WordPress vanilla con composer/installers). En un proyecto Bedrock con 25 plugins, la instalación con cache caliente corre en 30 a 90 segundos. Cache fría, sin directorio de cache de Composer, runner CI fresco: 2 a 4 minutos, principalmente tiempo de descarga. Ese número empieza a importar cuando encadenas composer install en cada build de PR.
Lo que el autoalojamiento realmente te aporta
Autoalojar WP Packages es la única funcionalidad que WPackagist no iguala. Tres escenarios reales del mercado español donde compensa:
- Cumplimiento AEPD y auditoría de cadena de suministro. Bancos (BBVA, Santander con dependencias WordPress en sitios corporativos secundarios), aseguradoras y administración pública regional tienen requisitos LOPDGDD que exigen que cada dependencia se sirva desde infraestructura controlada. Con WP Packages forkeas el proyecto, lo replicas en un endpoint interno en Stackscale, OVHcloud Datacenter Madrid, o un servidor dedicado de LucusHost, y tu composer.json deja de hablar con un host de terceros durante el despliegue.
- Runners CI en red cerrada. Jenkins o GitLab Runner dentro de una VPN bancaria o ministerial no alcanza wpackagist.org ni wp-packages.org. Con WP Packages autoalojado más una cache local Composer, el pipeline de despliegue es offline-clean.
- Filtrado personalizado. Un caso real de una agencia de Madrid: plugins no actualizados en más de 18 meses fueron bloqueados de instalación en infraestructura interna. Forkearon WP Packages, añadieron el filtro en tiempo de indexación, y
composer requireen un plugin desactualizado falla ahora con error claro en lugar de instalar silenciosamente código abandonado.
Para la mayoría de los equipos, WPackagist basta. Los casos anteriores son aquellos en los que deja de bastar.
WPackagist: sigue siendo el default por una razón
WPackagist lo gestiona Outlandish, una cooperativa británica. Replica el directorio WordPress.org desde 2013 con muy pocas caídas. La convención de nombres de paquete (wpackagist-plugin/woocommerce, wpackagist-theme/twentytwentyfour) se convirtió en convención de facto; casi todo tutorial Bedrock escrito antes de marzo 2026 asume WPackagist.
Comparación lado a lado
| Propiedad | WPackagist | WP Packages |
|---|---|---|
| Activo desde | 2013 | Marzo 2026 |
| Mantenido por | Outlandish | Roots |
| Código del repositorio open source | Cerrado | Sí (MIT) |
| Autoalojable | No | Sí |
| Prefijo de vendor | wpackagist-plugin/, wpackagist-theme/ | wp-packages/ |
| Método de sincronización | Cron consulta SVN de WordPress.org | Cron consulta API de WordPress.org |
| Default en esqueleto Bedrock | Sí (hoy) | No (cambio manual) |
| Trayectoria operativa | 12+ años | Pocas semanas |
Cuándo cambiar, cuándo no
Cambia a WP Packages si necesitas autoalojamiento, si ya estandarizaste todo el stack Roots y prefieres soporte de un solo proveedor, o si has visto un retraso de sincronización de WPackagist que rompió un build y quieres un segundo mirror como respaldo. Quédate con WPackagist si tu CI está verde, tu composer.lock es reproducible, y “migremos el prefijo de vendor en 200 sitios de cliente” no está en el roadmap de nadie.
Los dos no se excluyen mutuamente. Nada te impide declarar ambos repositorios y fijar plugins específicos a mirrors específicos. Eso es lo que la mayoría de las agencias terminarán haciendo en la práctica.
Bedrock, Sage, Trellis: donde Composer realmente compensa
El stack Roots es la razon por la que Composer-en-WordPress se siente nativo en lugar de atornillado.
Bedrock: el layout del proyecto
Bedrock es un esqueleto de proyecto, no un framework. Lo que efectivamente hace:
- Separa el core de WordPress en
web/wp/(gestionado por Composer), de modo quewp-config.phpes un loader fino en lugar del archivo de configuración canónico. - Mueve toda la configuración de entorno a
.env(leído porvlucas/phpdotenv) yconfig/environments/{development,staging,production}.php. La constanteWP_ENVcontrola qué archivo de entorno se carga. - Trata
web/app/plugins/,web/app/themes/yweb/app/mu-plugins/como destinos de instalación Composer víacomposer/installers. - Trae un autoloader
mu-plugins/register-theme-directory.phppara quecomposer requireen un tema lo registre realmente con WordPress.
.env está en gitignore. Los secretos de producción viven en el gestor de secretos (HashiCorp Vault, AWS Secrets Manager), no en wp-config.php. Este es el contrato que hace que WP_DEBUG, claves de licencia ACF Pro y credenciales de base de datos sean seguras por entorno. Para cumplimiento RGPD y la supervisión de la AEPD, esta separación entre código versionado y almacenamiento de secretos es prácticamente obligatoria.
composer create-project roots/bedrock mi-proyecto
cd mi-proyecto
cp .env.example .env
# editar .env con credenciales locales de DB y WP_ENV=development
composer install
Hosting español para Bedrock: LucusHost tiene SSH y Composer en plan Profesional y superiores, con documentación para Bedrock. Stackscale ofrece servidores dedicados con root para cualquier toolchain. Webempresa tiene SSH en plan M2 y superiores. Raiola Networks soporta Composer en planes Pro y superiores. Profesional Hosting ofrece SSH en planes Empresa y dedicado. Don Dominio Wordpress Pro también lo soporta. En general, evita hosting compartido sin SSH; en 2026 Composer-build-en-servidor es un antipatrón.
Sage 10 a Sage 11: el impuesto de migración
Sage es el tema de Roots. Sage 11 (lanzado en 2024) trajo Acorn, un contenedor estilo Laravel corriendo dentro de WordPress, más plantillas Blade en lugar de PHP plano. Las migraciones de Sage 10 a Sage 11 tienen modos de fallo específicos que conviene conocer antes de apuntarse:
- Cambios incompatibles de Acorn. Hooks registrados a través del mecanismo de service provider de Acorn se disparan después que los mismos hooks registrados en
functions.php. Código que asumía prioridad 10 eninitpuede necesitar moverse a prioridad 20 o a otro hook. - Blade vs plantillas PHP.
single.blade.phpen lugar desingle.php. Llamadas antiguas aget_template_partsiguen funcionando pero saltan la pipeline Blade y pierden la mecánica section/yield. - Pipeline de assets. Sage 10 usaba Bud (wrapper de Webpack 5); Sage 11 pasó a Vite. Archivos de configuración Bud no son portables. Tu
tailwind.config.jssí, pero ojo a diferencias en el orden de plugins PostCSS.
La migración no es un solo botón. Reserva dos días para un tema pequeño, una semana para algo con bloques Gutenberg personalizados.
Trellis: la opción que probablemente no necesitas
Trellis es Ansible más Vagrant para desarrollo local y aprovisionamiento remoto. Construye servidores Ubuntu LTS con Nginx, MariaDB, PHP-FPM, Redis y un pipeline de despliegue. En claro: Trellis es excelente para agencias con infraestructura propia (50 a 200 sitios en dedicados de Stackscale o Hetzner) y excesivo para todos los demás. Si despliegas a hosting WordPress gestionado (Webempresa Cloud, WP Engine, Kinsta), Trellis no es la herramienta correcta. Si gestionas tu propia flota DigitalOcean o Hetzner, sí lo es.
Modos de fallo que nadie menciona en la introducción
Estos son los cuatro modos en los que composer install arruina la tarde a alguien.
Drift de versión PHP entre local y CI
composer require resuelve contra la versión PHP que ve hoy. Un plugin marcado "php": ">=8.2" se instala bien en tu portátil con PHP 8.3. Un entorno staging congelado en PHP 8.1 fallará composer install con un error poco útil de platform-requirement. Fija config.platform.php en composer.json a la versión más baja que cualquier entorno ejecute:
{
"config": {
"platform": {
"php": "8.2.20"
}
}
}
Esta única línea salva más despliegues que cualquier optimización CI. Especialmente relevante para hosting compartido español donde PHP 8.1 y 8.2 siguen siendo default en planes antiguos de Webempresa, Raiola y LucusHost en 2026.
mu-plugins/register.php cargado contra la versión WordPress equivocada
El autoloader mu-plugins/ de Bedrock corre en tiempo de boot PHP, antes de que el core de WordPress se inicialice. Si haces composer update del core WordPress a una versión que cambió la semántica de WP_PLUGIN_DIR (pasó en WP 6.5), el autoloader puede registrar directorios de tema que ya no existen. Síntoma: pantalla blanca en producción, OK en staging. Solución: bloquea roots/wordpress a una minor conocida buena y sube deliberadamente.
Activación de licencia ACF Pro en entornos de despliegue
ACF Pro autentica su licencia contra advancedcustomfields.com. Builds de artefacto de despliegue (Bitbucket Pipelines, GitHub Actions) corren como contenedor fresco sin DOM, sin sesión de admin, y con IP que el servidor de licencias de ACF nunca ha visto. El flujo de activación que funciona en wp-admin no funciona en un runner CI. Soluciones que de verdad funcionan en 2026:
- Usa el proxy Roots Premium si estás en plan de organización Roots (intermedia ACF Pro y otras licencias premium a través de Composer).
- Pon
ACF_PRO_LICENSEcomo variable de entorno leída por la API PHP de ACF y omite el flujo de activación del dashboard por completo. - Usa HTTP basic auth de Composer (
auth.json) para autenticar contra el endpoint Composer oficial de ACF enconnect.advancedcustomfields.com.
Las dos primeras son las únicas que sobreviven a una migración de servidor sin intervención manual.
Incompatibilidad de lockfile Composer 2.7 vs Composer 2.6
Composer 2.7 cambió cómo composer.lock registra platform overrides. Un composer.lock escrito por 2.7 falla la instalación en 2.6 con un error confuso “the lock file is not up to date”. Estandariza la versión de Composer en CI (composer self-update 2.7.7) y documéntalo en el README. Sí, esto es molesto. Sí, ha mordido a suficientes equipos como para que Composer 2.8 vaya a avisar explícitamente.
Plugins premium: la parte que la documentación omite
La mitad de los plugins en un sitio de cliente real no están en el directorio WordPress.org. ACF Pro, Gravity Forms, WP Migrate, GP Premium, FacetWP, WP All Import Pro. En contexto español, añade frecuentemente Cookiebot o Complianz para cumplimiento RGPD/AEPD, y a menudo Yoast Premium o RankMath Pro. El soporte Composer varía mucho:
- ACF Pro: endpoint Composer oficial en
connect.advancedcustomfields.com. Funciona bien, requiereauth.jsoncon clave de licencia como password. - Gravity Forms: soporte oficial Composer desde 2023. Clave de licencia en
auth.json, nombre de paquetegravityforms/gravityforms. - Cookiebot/Complianz: sin endpoint oficial Composer. SatisPress o inclusión manual.
- WP Migrate Pro (Delicious Brains, ahora WP Engine): descarga ZIP con URL de licencia. Repositorio Composer personalizado declarando el paquete como tipo
packagecon URL inline, o proxy vía SatisPress. - WP All Import Pro: sin endpoint Composer. ZIPs alojados en URL con clave de licencia. SatisPress o commit del ZIP a un repositorio privado.
Tres patrones cubren todo lo anterior:
- Roots Premium (roots.io/premium). Un proxy Composer gestionado que maneja licencias para ACF Pro, Gravity Forms y otros. Precio individual; para agencias que llevan 50+ sitios la cuenta normalmente cuadra.
- SatisPress. Un plugin WordPress que convierte tu propia instalación WordPress en un repositorio Composer. Instala plugins premium normalmente, exponlos vía
https://tu-host-privado/satispress/, asegúralos con HTTP basic auth. - Private Packagist de packagist.com. Repositorio Composer alojado con soporte a paquetes privados. Cuesta más que SatisPress, requiere cero infraestructura.
Sea cual sea la elección, la regla es: las claves de licencia nunca van en composer.json o auth.json versionado en git. Viven en variables de entorno leídas en tiempo de instalación, o en secretos CI inyectados en auth.json durante el paso de build. El cumplimiento RGPD exige separación clara entre código versionado y almacén de credenciales.
Integracion CI que sobrevive a la realidad
Una pipeline de despliegue funcional:
# .github/workflows/deploy.yml (extracto)
- name: Set up PHP 8.2
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
tools: composer:2.7
- name: Cache Composer
uses: actions/cache@v4
with:
path: ~/.composer/cache
key: composer-${{ hashFiles('composer.lock') }}
- name: Install
run: composer install --no-dev --optimize-autoloader --prefer-dist --no-interaction
env:
COMPOSER_AUTH: ${{ secrets.COMPOSER_AUTH_JSON }}
- name: Deploy artifact
run: rsync -avz --delete --exclude='.git' --exclude='node_modules' ./ deploy@host:/var/www/html/
Tres reglas que ahorran tiempo de debug:
- Nunca ejecutes
composer updateen CI. Actualiza en local, haz commit del nuevocomposer.lock, push. CI ejecutacomposer installcontra exactamente ese lockfile. - Cachea
~/.composer/cachecon hash decomposer.lockcomo clave. Instalaciones frías bajan de 4 minutos a 30 segundos. - Inyecta
auth.jsondesde un secreto. La variable de entornoCOMPOSER_AUTHes leída nativamente por Composer. Nunca hagas commit de credenciales licenciadas.
Lo que cambió en la cultura WordPress en 2026
Composer-en-WordPress era antes cosa de tienda Roots. En 2026 es el default para cualquier agencia española o equipo interno que despliegue a más de un entorno. Tres señales del ecosistema más amplio:
- Las publicaciones de plugins en WordPress.org superaron las 500 por semana a inicios de 2026, frente a 100 a 150 semanales durante 2022 a 2024 (fuente: informes semanales del Plugin Review Team). La mayor parte del nuevo volumen es código asistido por IA. El equipo de Plugins recluta revisores voluntarios; el listón de calidad del directorio está bajo presión.
- Tanto Kinsta como WP Engine añadieron soporte nativo a builds Composer en su despliegue Git push a finales de 2025. Webempresa Cloud siguió una ruta similar en el primer trimestre de 2026. La categoría “managed WordPress hosting que ignora composer.json” se encoge.
- WP-CLI 2.10 añadió subcomandos
wp composerque envuelvencomposer install,composer updatey validación de lockfile. Composer se convierte en parte de la superficie oficial de WP-CLI.
La lección para gestión de plugin-como-dependencia: las herramientas maduran más rápido que la capacidad de revisión del directorio WordPress.org. Un mirror autoalojable como WP Packages es más útil en este contexto que lo habría sido hace cinco años, cuando el directorio era un jardín cerrado en el que todos confiaban por defecto.
Última actualización: 2026-04-01
¿Necesitas ayuda para migrar un sitio a Bedrock o configurar una pipeline de despliegue dirigida por Composer? Mira nuestros servicios de desarrollo WordPress.
