¿Qué es npm y qué gestiona en un proyecto?
npm es el gestor de paquetes que normalmente acompaña a Node.js. Su función principal es descargar, instalar y actualizar librerías (paquetes) que tu proyecto necesita, además de registrar esa información en archivos del proyecto para que cualquier persona (o servidor) pueda reproducir exactamente el mismo entorno de dependencias.
En un proyecto Node.js típico, npm se apoya en dos archivos clave:
package.json: describe el proyecto (nombre, versión) y declara dependencias, scripts y metadatos.package-lock.json: fija versiones exactas y el árbol completo de dependencias instaladas para instalaciones reproducibles.
Inicializar un proyecto: creando package.json
Paso a paso con npm init
En la carpeta de tu proyecto, inicializa el archivo package.json:
npm initEsto te hará preguntas (nombre, versión, etc.). Si quieres aceptar valores por defecto rápidamente:
npm init -yEjemplo mínimo de package.json (simplificado):
- Escuche el audio con la pantalla apagada.
- Obtenga un certificado al finalizar.
- ¡Más de 5000 cursos para que explores!
Descargar la aplicación
{ "name": "mi-backend", "version": "1.0.0", "main": "index.js", "scripts": { "start": "node index.js" }}En proyectos con Express es común que el punto de entrada sea index.js o src/server.js. Lo importante es que el script start apunte al archivo correcto.
Dependencias vs dependencias de desarrollo
¿Cuál es la diferencia?
- dependencies: paquetes necesarios para que la aplicación funcione en producción (por ejemplo,
express). - devDependencies: paquetes usados solo durante el desarrollo o pruebas (por ejemplo,
nodemon, linters, frameworks de test).
Instalar dependencias (producción)
Para instalar Express como dependencia de ejecución:
npm install expressEsto añadirá una entrada en dependencies dentro de package.json.
Instalar dependencias de desarrollo
Para instalar una herramienta solo para desarrollo:
npm install -D nodemonEsto la registrará en devDependencies.
Tabla rápida de comandos
| Acción | Comando | Dónde se registra |
|---|---|---|
| Instalar dependencia | npm i paquete | dependencies |
| Instalar devDependency | npm i -D paquete | devDependencies |
| Instalar versión exacta | npm i paquete@1.2.3 | Según el tipo |
Comprender package-lock.json (y por qué no debes borrarlo)
Cuando instalas paquetes, npm resuelve un árbol de dependencias: tu proyecto depende de Express, Express depende de otros paquetes, etc. package-lock.json guarda:
- Versiones exactas instaladas (no solo rangos).
- El árbol completo de dependencias y subdependencias.
- Información para que
npm installsea reproducible y más rápido.
Buenas prácticas:
- Incluye
package-lock.jsonen el control de versiones (por ejemplo, Git) para que el equipo instale lo mismo. - Evita editarlo manualmente; deja que npm lo gestione.
- Si hay conflictos en PRs, resuélvelos reinstalando dependencias y regenerando el lock de forma consistente.
Scripts típicos: start, dev y test
Los scripts son atajos definidos en package.json para ejecutar comandos comunes con npm run. Ejemplo recomendado para un backend simple:
{ "scripts": { "start": "node src/server.js", "dev": "nodemon src/server.js", "test": "node --test" }}Cómo ejecutar scripts
npm startejecuta el scriptstart(es un alias especial, no requiererun).npm run devejecuta el scriptdev.npm testejecuta el scripttest(también es alias especial).
Nota: si aún no usas el runner de tests integrado de Node (node --test), puedes dejar test como placeholder:
{ "scripts": { "test": "echo \"No hay tests aún\" && exit 0" }}Reinicio automático en desarrollo con nodemon
Cuando desarrollas un servidor Express, es incómodo reiniciar manualmente cada vez que cambias un archivo. nodemon observa cambios y reinicia el proceso automáticamente.
Paso a paso
- 1) Instala nodemon como dependencia de desarrollo:
npm install -D nodemon- 2) Crea (o verifica) tu archivo de entrada, por ejemplo
src/server.js:
const express = require('express'); const app = express(); const PORT = process.env.PORT || 3000; app.get('/health', (req, res) => res.json({ ok: true })); app.listen(PORT, () => { console.log(`Servidor escuchando en http://localhost:${PORT}`); });- 3) Define el script
dev:
{ "scripts": { "dev": "nodemon src/server.js" }}- 4) Ejecuta el modo desarrollo:
npm run devConfiguración opcional con nodemon.json
Si quieres controlar qué archivos observar o ignorar, puedes crear nodemon.json:
{ "watch": ["src"], "ext": "js,json", "ignore": ["node_modules"], "exec": "node src/server.js"}Y tu script puede quedar más simple:
{ "scripts": { "dev": "nodemon" }}Buenas prácticas al instalar y actualizar dependencias
1) Entender rangos de versiones (SemVer) en package.json
En package.json verás versiones con símbolos como ^ o ~. Ejemplos:
"express": "^4.18.2": permite actualizar automáticamente minor y patch (4.x.x) sin cambiar el major."express": "~4.18.2": permite solo cambios patch (4.18.x)."express": "4.18.2": fija exactamente esa versión (menos flexible).
En equipos, suele ser razonable usar ^ para librerías maduras, pero siempre apoyándote en package-lock.json para reproducibilidad.
2) Preferir npm ci en entornos reproducibles
Cuando ya existe package-lock.json (por ejemplo en CI/CD), usa:
npm cinpm ci instala exactamente lo que indica el lockfile y falla si package.json y package-lock.json no están alineados. Es más rápido y predecible que npm install en pipelines.
3) Actualizar dependencias de forma controlada
- Para actualizar un paquete a la última versión permitida por el rango actual:
npm update- Para instalar una versión específica (por ejemplo, al corregir un bug):
npm install express@4.19.0- Para ver qué está desactualizado:
npm outdatedRecomendación práctica: actualiza en pequeños pasos, ejecuta tu app y tests (si existen) después de cada actualización relevante, y revisa cambios mayores (major) con más cuidado.
4) No instalar globalmente lo que debe ir en el proyecto
Herramientas como nodemon conviene instalarlas en el proyecto (-D) para que todos usen la misma versión. Así, npm run dev funciona igual en cualquier máquina.
5) Mantener limpio el repositorio
Normalmente no se versiona node_modules. Asegúrate de ignorarlo en tu control de versiones (por ejemplo, en .gitignore):
node_modulesAuditoría básica de vulnerabilidades con npm audit
npm puede analizar dependencias conocidas con vulnerabilidades reportadas y sugerir correcciones.
Ejecutar una auditoría
npm auditEsto muestra un reporte con severidad, paquetes afectados y rutas de dependencia.
Aplicar correcciones automáticas (cuando sea seguro)
- Intento de corrección sin cambios disruptivos:
npm audit fix- Corrección más agresiva (puede introducir cambios mayores):
npm audit fix --forceBuenas prácticas al usar npm audit fix:
- Prefiere primero
npm audit fixsin--force. - Si consideras
--force, revisa qué paquetes cambiarán de versión mayor y prueba tu aplicación. - Si una vulnerabilidad viene de una subdependencia, a veces la solución es actualizar el paquete principal que la trae.