¿Qué es npm?
npm es el gestor de paquetes predeterminado para JavaScript y el registro de software más grande del mundo. Se distribuye junto con Node.js, instala las dependencias que declara tu proyecto, resuelve sus versiones y te proporciona un ejecutor de tareas consistente a través de scripts.
Casi todos los proyectos de JavaScript dependen de npm, incluso si utilizan un cliente diferente internamente. Comprender qué hace realmente —cómo se resuelven las versiones, para qué sirve el lockfile y por qué CI utiliza un comando diferente— elimina toda una categoría de errores confusos.
package.json
El manifiesto describe tu proyecto. Contiene metadatos, dependencias y scripts.
{
"name": "my-app",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"test": "vitest run",
"lint": "eslint ."
},
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"vite": "^6.0.0",
"vitest": "^3.0.0"
}
}
dependencies son necesarias en tiempo de ejecución; devDependencies son herramientas utilizadas para desarrollar y construir. El flag private evita la publicación accidental, y type: "module" activa el uso de ES modules.
Rangos de versiones
npm utiliza el versionado semántico: major.minor.patch. Un rango en package.json describe qué actualizaciones aceptas.
| Rango | Significado | Permite |
|---|---|---|
1.2.3 |
exacta | nada |
~1.2.3 |
actualizaciones de patch | 1.2.4, 1.2.5 |
^1.2.3 |
minor y patch | 1.3.0, 1.4.2 |
* |
cualquier cosa | cualquier versión |
El caret (^) es el valor predeterminado y la opción más sensata para la mayoría de las dependencias. Las versiones exactas bloquean las correcciones de errores y los parches de seguridad, mientras que el lockfile ya garantiza la reproducibilidad.
El lockfile
package-lock.json registra la versión exacta y el hash de integridad de cada paquete en el árbol, incluyendo las dependencias transitivas.
- Súbelo al control de versiones (commit).
- Nunca lo edites manualmente.
- Regenéralo deliberadamente cuando tengas la intención de actualizar.
- Deja que sea la única fuente de verdad para las versiones instaladas.
Sin un lockfile, dos instalaciones del mismo package.json pueden producir árboles diferentes, y un error que solo aparece en producción se vuelve casi imposible de reproducir.
Instalación de dependencias
Los dos comandos principales de instalación tienen propósitos diferentes.
# development: resolve ranges, may update the lockfile
npm install
# CI and clean environments: exact install from the lockfile
npm ci
# add a runtime dependency
npm install zod
# add a development tool
npm install -D vitest
npm ci elimina node_modules, instala estrictamente desde el lockfile y falla si package.json y el lockfile no coinciden. Esto lo hace más rápido y seguro en CI. Usa npm install localmente cuando estés modificando las dependencias.
Scripts
Los scripts son comandos con nombre que se ejecutan a través de npm run. Son la forma en que un proyecto expone una interfaz consistente para todos, incluyendo la CI.
npm run dev
npm run build
npm test # shorthand for npm run test
Los scripts pueden llamar a binarios locales directamente, por lo que "dev": "vite" funciona sin necesidad de una instalación global. También son componibles: un script de ci puede ejecutar lint, test y build en orden. Mantener estos comandos en package.json evita que alguien tenga que recordar la invocación exacta.
npx y workspaces
npx ejecuta el binario de un paquete sin necesidad de una instalación global, lo cual es ideal para herramientas de uso puntual.
npx create-vite@latest my-app
npx eslint .
Los Workspaces permiten que un único repositorio contenga varios paquetes que comparten un mismo node_modules y lockfile.
{
"workspaces": ["packages/*", "apps/*"]
}
npm vincula los paquetes entre sí, permitiendo que un workspace dependa de otro hermano sin necesidad de publicarlo. Para monorepos más grandes, herramientas como Turborepo añaden capas de almacenamiento en caché y orquestación de tareas.
Seguridad y mantenimiento
npm incluye un comando de auditoría que verifica tu árbol de dependencias en busca de vulnerabilidades conocidas.
npm audit
npm audit fix
npm outdated
Realiza auditorías regularmente y analiza los resultados en lugar de ejecutar a ciegas fix, ya que esto podría introducir cambios que rompan tu código. npm outdated muestra qué dependencias tienen versiones más recientes disponibles, lo que te ayuda a planificar las actualizaciones en lugar de dejar que se acumulen.
Mejores prácticas
- Haz commit de
package-lock.jsony nunca lo edites manualmente. - Usa
npm cien CI ynpm installsolo cuando cambies las dependencias. - Mantén separadas las dependencies y las devDependencies.
- Prefiere los rangos con caret (^) y deja que el lockfile fije las versiones exactas.
- Define scripts para cada tarea común.
- Ejecuta
npm auditynpm outdatedde forma programada. - Usa workspaces para monorepos en lugar de repositorios separados.
Errores comunes
- Borrar el lockfile para “solucionar” problemas de instalación.
- Ejecutar
npm installen CI y obtener builds no reproducibles. - Incluir herramientas de build en
dependenciese inflar las instalaciones de runtime. - Ignorar las advertencias de audit hasta que se vuelven urgentes.
- Instalar paquetes de forma global cuando
npxo una devDependency serían suficientes. - Editar
node_modulesy esperar que el cambio persista.
Próximos pasos
npm es la base de la cadena de herramientas de JavaScript. Compáralo con pnpm para mejorar la velocidad y la eficiencia de disco, comprende el entorno de ejecución de Node.js con el que se distribuye y añade Turborepo cuando tu repositorio crezca hasta convertirse en un monorepo. Después, optimiza los scripts de tu proyecto para que todo el equipo comparta un mismo conjunto de comandos.