Composer en 2026: gestión de dependencias PHP que ya no tiene excusas

Composer es un gestor de dependencias para PHP. Eso significa que se encarga de descargar las librerías que necesita tu proyecto, mantenerlas en la versión correcta y generar el autoloader para que puedas usarlas sin tener que hacer require a mano en cada archivo.

Antes de que apareciera en 2012, las opciones eran copiar archivos PHP de una librería a otra a mano o usar PEAR, que era la herramienta oficial pero funcionaba bastante mal. Hoy cualquier proyecto PHP mínimamente serio usa Composer. Packagist, el repositorio central de paquetes, tiene más de 300.000 paquetes disponibles, desde frameworks enteros como Laravel o Symfony hasta utilidades pequeñas para trabajar con fechas, tokens JWT o PDFs.

Si arrancas un proyecto PHP en 2026 sin Composer, vas a tener que justificarlo.

composer.json y composer.lock: para qué sirve cada uno

Estos dos archivos son los que más confusión generan al principio, pero la distinción es sencilla:

  • composer.json: lo defines tú. Aquí dices qué paquetes necesita tu proyecto y con qué restricciones de versión.
  • composer.lock: lo genera Composer. Contiene las versiones exactas de todos los paquetes instalados, incluyendo las dependencias de tus dependencias.

El archivo composer.lock debe ir siempre en el repositorio de git. Si no lo subes, cuando alguien ejecute composer install en producción puede que instale versiones distintas a las que tienes en local, y eso es una fuente de bugs bastante desagradables.

La diferencia entre composer install y composer update también conviene tenerla clara:

  • composer install: instala exactamente lo que dice el lockfile. Es lo que debes usar en producción y en CI.
  • composer update: resuelve las dependencias de nuevo según las restricciones del composer.json, actualiza los paquetes a las versiones más recientes posibles y regenera el lockfile. Úsalo solo cuando quieras actualizar paquetes de forma intencionada.

Restricciones de versión: qué significa cada símbolo

Cuando añades una dependencia en composer.json, especificas una restricción de versión. Las más habituales son:

"require": {
    "monolog/monolog": "^2.0",
    "guzzlehttp/guzzle": "~7.4",
    "vendor/legacy-lib": "1.3.2"
}
  • "^2.0": cualquier versión >=2.0.0 y <3.0.0. Respeta semver y es la restricción más usada.
  • "~2.1": cualquier versión >=2.1.0 y <2.2.0. Más restrictivo que el caret.
  • "*": cualquier versión. Nunca lo uses en producción.
  • "1.3.2": exactamente esa versión. Muy restrictivo y raramente necesario cuando ya tienes lockfile.
  • "dev-main": la rama main del repositorio. Solo para desarrollo local o cuando necesitas algo que aún no tiene release.

El caret (^) funciona bien para la mayoría de los casos porque respeta semver: si el autor del paquete sigue correctamente el versionado semántico, una versión minor nunca debería romperte el código.

Autoloading: cómo Composer carga las clases

Una de las cosas más útiles de Composer es que genera el autoloader automáticamente. En vez de hacer require_once a cada clase, añades una sola línea al principio de tu aplicación:

<?php
require_once __DIR__ . '/vendor/autoload.php';

Y a partir de ahí, todas las clases de tus dependencias y las tuyas propias están disponibles. Para que Composer sepa dónde están tus clases, tienes que decírselo en composer.json:

"autoload": {
    "psr-4": {
        "App\": "src/"
    }
}

Esto significa que las clases bajo el namespace App se buscan en la carpeta src/. Por ejemplo, AppControllersUserController corresponde al archivo src/Controllers/UserController.php.

PSR-4 es el estándar que usa prácticamente todo el mundo. Si tienes código legacy sin namespaces, puedes usar classmap en su lugar, que escanea directorios y mapea clases directamente.

Cada vez que añades carpetas nuevas o cambias la estructura, ejecuta:

composer dump-autoload

Esto regenera el mapa de clases. En producción conviene añadir --optimize para que genere un classmap estático en vez de usar reglas PSR-4 dinámicas, lo que acelera la carga de clases.

Scripts de Composer

Composer permite definir scripts que puedes ejecutar con composer run. No tienen por qué ser solo PHP:

"scripts": {
    "test": "phpunit --testdox",
    "lint": "php-cs-fixer fix src/ --dry-run",
    "analyse": "phpstan analyse src/ --level=8"
}

Para ejecutar uno:

composer run test

También puedes definir hooks que se ejecutan automáticamente en determinados momentos. Los más usados son post-install-cmd y post-update-cmd, que se disparan justo después de instalar o actualizar dependencias:

"scripts": {
    "post-install-cmd": [
        "php artisan migrate --force",
        "php artisan config:cache"
    ]
}

Si necesitas ejecutar un hook manualmente:

composer run-script post-install-cmd

Paquetes privados y repositorios alternativos

No todos los paquetes están en Packagist. Si tienes librerías internas o de pago, puedes añadir repositorios alternativos en composer.json:

"repositories": [
    {
        "type": "vcs",
        "url": "[email protected]:miempresa/mi-paquete"
    }
]

Con esto, Composer busca en ese repositorio de Git además de en Packagist. Funciona bien para paquetes privados en GitHub, GitLab o Bitbucket.

Si tienes varios paquetes internos, montar Satis puede tener sentido. Es un Packagist privado que puedes alojar tú mismo, de código abierto y mantenido por los mismos autores de Composer. La alternativa gestionada es Private Packagist, de pago pero sin infraestructura que mantener.

Composer 2.x: qué cambió desde 2020

Composer 2 se lanzó en 2020 y fue un cambio importante en rendimiento. La resolución de dependencias pasó a ser paralela, lo que reduce considerablemente el tiempo de instalación en proyectos grandes. Si tienes algún servidor de CI que sigue con Composer 1, es el momento de actualizarlo.

Composer 2 también mejoró el sistema de plugins con sandboxing de permisos. Los plugins ahora declaran qué operaciones necesitan hacer, lo que reduce el riesgo de que un plugin malicioso haga cosas que no debería.

Dos comandos que conviene conocer si no los usas ya:

# Comprueba si alguna dependencia tiene vulnerabilidades conocidas
composer audit

# Muestra qué paquetes tienen versiones más nuevas disponibles
composer outdated

composer audit consulta la base de datos de advisories de seguridad de Packagist. Es rápido y puede ahorrarte un susto. Tiene sentido ejecutarlo en CI junto con los tests.

Buenas prácticas en 2026

Algunas cosas que marcan la diferencia en el día a día:

En producción, siempre con estas opciones

composer install --no-dev --optimize-autoloader

--no-dev excluye las dependencias de desarrollo (PHPUnit, PHPStan, etc.) y --optimize-autoloader genera un classmap estático en vez de usar autoloading dinámico. Los dos juntos reducen el peso de vendor/ y aceleran un poco la aplicación.

Separa las dependencias de desarrollo

composer require --dev phpunit/phpunit
composer require --dev phpstan/phpstan

Todo lo que solo necesitas para desarrollar o testear va con --dev. Así no acabas instalando PHPUnit en producción.

Actualiza con cuidado

En vez de ejecutar composer update a secas (que actualiza todo), actualiza paquete a paquete:

composer update vendor/paquete

Esto limita el alcance del cambio y hace más fácil detectar qué actualización introdujo un problema si algo falla.

Comandos útiles para el día a día

# Por qué está instalado este paquete
composer why vendor/paquete

# Qué dependencias bloquean la actualización a PHP 8.4
composer prohibits php 8.4

# Ver todas las dependencias en forma de árbol
composer depends vendor/paquete

composer why es especialmente útil cuando encuentras un paquete en vendor/ que no recuerdas haber instalado directamente. Te dice qué dependencia lo requirió.

No cometas vendor/

La carpeta vendor/ no va en git. Añádela al .gitignore. Lo que sí va en git es composer.lock, que es suficiente para reproducir exactamente el mismo estado en cualquier máquina.

Si tienes un entorno sin acceso a internet en producción, la opción es usar composer install --no-interaction antes del despliegue o crear un paquete vendor.tar.gz en CI y desplegarlo junto con el código.

Recursos para seguir

La documentación oficial de Composer en getcomposer.org está bastante bien mantenida y cubre todos los casos de uso que puedas necesitar. Para Composer en el flujo TDD: gestión de dependencias para testing y para saber más sobre seguridad en paquetes PHP: composer audit y vulnerabilidades, tienes más contexto en estos artículos.

Imagen: Pexels / Daniil Komov

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP