Inicio / Artículos / Qué hace realmente npm install: registro, package.json y archivos de bloqueo

Qué hace realmente npm install: registro, package.json y archivos de bloqueo

Una guía práctica de npm: el registro y la CLI, cómo npm install resuelve los paquetes, qué registran package.json y package-lock.json, y cómo publicar.

1605 palabras

Casi todo proyecto en JavaScript, ya sea que se ejecute en Node.js, React o Next.js, comienza con el mismo comando, y muchos desarrolladores lo ejecutan a diario sin tener una idea clara de qué hace. Saber de dónde provienen los paquetes, cómo decide npm qué instalar y para qué sirven package.json, package-lock.json y node_modules respectivamente, facilita la depuración de instalaciones defectuosas. Esta guía aborda cada uno de estos aspectos, desde la primera instalación hasta la publicación de tu propio paquete.

Los comandos que todos usan

La forma más habitual consiste en instalar todo lo que ya ha sido declarado por el proyecto:

npm install

Igualmente común es agregar una biblioteca por su nombre, como el framework web Express:

npm install express

o el cliente HTTP Axios:

npm install axios

Detrás de estas líneas simples se esconden algunas preguntas. ¿De dónde se descarga el código? ¿Cómo sabe npm de qué depende un proyecto? ¿Para qué sirve package.json? ¿Y por qué node_modules crece tanto?

Qué es npm

npm es el gestor de paquetes predeterminado para Node.js y viene incluido con él. Te da acceso a un enorme catálogo de paquetes reutilizables publicados por otros desarrolladores, para que puedas incorporar código probado a tu proyecto en lugar de escribirlo tú mismo.

Piénsalo como una biblioteca pública de código. Supongamos que un backend de Node.js necesita un servidor HTTP. En lugar de crear la lógica de enrutamiento y los intermediarios desde cero, simplemente añades Express:

npm install express

¿Necesitas llamar a otras APIs? Agrega un cliente HTTP:

npm install axios

La validación de los datos recibidos contra un esquema la realiza Zod:

npm install zod

Y bcrypt se encarga de hashear las contraseñas:

npm install bcrypt

Esa es la mayor ventaja del ecosistema: cuando existe una solución bien probada, rara vez hay motivo para crearla uno mismo. Por otro lado, cada paquete instalado es código en el que ahora debes confiar, por lo que es preferible utilizar bibliotecas mantenidas y ampliamente utilizadas, manteniendo la lista reducida. Consulta cómo funcionan los ataques a la cadena de suministro de npm para entender por qué esto es importante.

Un ecosistema, no solo una orden

Los principiantes a menudo ven npm como simplemente una palabra que se escribe en la terminal. En realidad, el nombre abarca varias partes que colaboran entre sí:

  • El registro de npm: el servicio público desde donde se publican y descargan los paquetes.
  • La CLI de npm: la herramienta de línea de comandos que se comunica con el registro y gestiona las dependencias.
  • Paquetes: las unidades reutilizables de código en sí.
  • package.json: el manifiesto que describe tu proyecto y de qué depende.
  • Los paquetes públicos son gratuitos: puedes instalar cualquier cosa pública sin necesidad de cuenta. Esa baja barrera ayudó a que el JavaScript de código abierto se difundiera por todo el mundo. Solo se necesita una cuenta para publicar.

    Qué sucede cuando ejecutas npm install

    Toma un proyecto que agrega Express:

    npm install express
    

    A nivel general:

    1. npm busca el paquete en el registro y selecciona una versión que coincida con el rango solicitado (la más reciente si no se especifica ninguno).
    2. Resuelve las dependencias propias del paquete y las de estas, formando un árbol completo.
    3. Descarga todo lo que aún no está en caché y lo coloca en node_modules.
  • Registra la dependencia en package.json y el árbol resuelto exacto en package-lock.json.
  • Así es como un único comando breve permite acceder a todo un conjunto de funcionalidades.

    package.json: el manifiesto del proyecto

    Hay un archivo en el corazón de cada proyecto Node.js:

    package.json
    

    Funciona como la tarjeta de identidad y la configuración de tu proyecto en uno solo, conteniendo el nombre, versión, descripción, scripts, dependencias de ejecución y de desarrollo, además de los detalles del autor. Un ejemplo mínimo declara un archivo de entrada en main, un script y una sola dependencia:

    {
      "name": "my-project",
      "version": "1.0.0",
      "description": "My Node.js application",
      "main": "index.js",
      "scripts": {
        "start": "node index.js"
      },
      "dependencies": {
        "express": "^5.1.0"
      }
    }
    

    name

    name identifica el proyecto o paquete. Si lo publicas, esto es lo que la gente escribirá para instalarlo, por lo que debe ser único en el registro.

    "name": "my-project"
    

    version

    version contiene la versión actual del paquete.

    "version": "1.0.0"
    

    Es de suma importancia al publicar. npm utiliza la versionado semántico (MAJOR.MINOR.PATCH): los cambios que rompen la compatibilidad aumentan el número mayor, las características compatibles modifican el número menor y las correcciones afectan al número de parche.

    description

    description es un resumen de una línea sobre qué hace el proyecto, que se muestra en los resultados de búsqueda del registro.

    "description": "My Node.js application"
    

    scripts

    scripts define atajos con nombre para comandos frecuentes. Aquí start inicia el archivo de entrada:

    "scripts": {
      "start": "node index.js"
    }
    

    Sin él tendrías que escribir el comando completo:

    node index.js
    

    Con él, esto hace lo mismo:

    npm start
    

    El valor es la consistencia: cada colaborador y cada tarea de CI ejecutan el mismo comando con nombre. Los nombres personalizados como build se ejecutan con npm run build.

    Dependencias: de qué depende tu proyecto

    Imagínese una plataforma de entrega de alimentos. Su backend podría utilizar:

    • Express para las APIs
    • Zod para la validación
    • bcrypt para el hash de contraseñas
    • una biblioteca de tokens web JSON para la autenticación
    • Mongoose para MongoDB

    Cada uno de ellos es una dependencia. Cuando instala uno:

    npm install express
    

    npm agrega una entrada en package.json:

    "dependencies": {
      "express": "^5.1.0"
    }
    

    El símbolo de careta en ^5.1.0 indica un rango: se aceptan todas las versiones 5.x posteriores, pero no 6.0.0. Esta entrada indica a quienes lean el proyecto que necesita Express para funcionar. Las herramientas necesarias solo durante el desarrollo, como los ejecutores de pruebas, se incluyen en devDependencies mediante npm install --save-dev.

    Por qué una sola orden sirve para todo un equipo

    Supongamos que se une a un equipo y clona su repositorio. Nadie espera que obtenga cincuenta bibliotecas manualmente. Usted ejecuta:

    npm install
    

    npm lee las dependencias declaradas e instala todas ellas. La reconstrucción de un entorno funcional a partir de una descripción es la razón por la cual los gestores de paquetes son indispensables.

    node_modules: donde reside el código instalado

    Después de una instalación, aparece una nueva carpeta:

    node_modules/
    

    Contiene los paquetes que solicitó además de todo aquello de lo que dependen, y por eso crece en tamaño. Una estructura típica:

    my-project/
    │
    ├── node_modules/
    ├── package.json
    ├── package-lock.json
    └── index.js
    

    No incluya node_modules en Git. Es grande, puede contener compilaciones específicas de la plataforma y siempre se puede regenerar. Colóquelo en .gitignore e incluya en su lugar estos archivos:

    package.json
    package-lock.json
    

    Cualquier otra persona podrá entonces ejecutar:

    npm install
    

    y recuperar las mismas dependencias.

    package-lock.json: el registro exacto

    Hay un segundo archivo junto al manifiesto:

    package-lock.json
    

    ¿Por qué ambos? La versión breve:

    • package.json indica qué necesita el proyecto, generalmente en forma de rangos.
    • package-lock.json registra exactamente qué se instaló: cada versión de paquete en todo el árbol, además de los hashes de integridad.

    Dado que los rangos pueden coincidir con versiones más recientes con el tiempo, el archivo de bloqueo mantiene las computadoras portátiles, los compañeros de equipo y el CI con versiones idénticas. Guárdelo y prefiera npm ci en el CI, ya que instala estrictamente a partir del archivo de bloqueo.

    Comandos de npm que vale la pena conocer

    Agregar un paquete:

    npm install express
    

    Instalar todo lo que declara el proyecto:

    npm install
    

    Eliminar un paquete de node_modules y package.json:

    npm uninstall express
    

    Actualizar los paquetes a las versiones más recientes que permiten los rangos (no se cruzará una versión mayor):

    npm update
    

    Imprimir la versión de npm:

    npm -v
    

    Imprimir la versión de Node.js:

    node -v
    

    Mostrar la cuenta de npm con la que está conectado:

    npm whoami
    

    De consumidor a editor

    También puede contribuir con paquetes. Publique una biblioteca útil y otros la instalarán como cualquier otra:

    npm install your-package
    

    Ese bucle mantiene vivo el código abierto: se construye sobre el trabajo de otros, se crea propio y luego se comparte de vuelta.

    Paso a paso para publicar

    Necesita una cuenta de npm. Inicie sesión desde la terminal:

    npm login
    

    Confirme qué cuenta está activa:

    npm whoami
    

    Acceder al proyecto:

    cd myproject
    

    Asegúrese de que tenga un manifiesto válido con un name único y una version:

    package.json
    

    Luego publique:

    npm publish
    

    El paquete ahora está disponible para todos. Dos consejos: ejecute primero npm pack --dry-run para ver qué archivos se incluirán, y aumente la version en cada lanzamiento, ya que una versión publicada no puede reutilizarse. Consulte la documentación actual de npm sobre los requisitos de seguridad de las cuentas, como la autenticación de dos factores.

    Cómo encajan las partes

    Todo el flujo se ve así:

    Developer
        ↓
    npm install
        ↓
    npm Registry
        ↓
    Package + Dependencies
        ↓
    node_modules
        ↓
    package.json
        ↓
    Your Application
    

    Ejecuta la orden, la CLI obtiene los paquetes del registro, el código se almacena en node_modules, el manifiesto y el archivo de bloqueo lo registran, y su aplicación lo importa. Esa cadena es la que permite a los desarrolladores reutilizar, gestionar, compartir y publicar código de manera eficiente.

    Puntos clave

    Npm puede parecer un montón de comandos de terminal, pero una vez que se entiende lo que ocurre detrás de ellos:

    npm install
    

    El sistema se vuelve fácil de comprender. JavaScript proporciona el lenguaje, Node.js el entorno de ejecución y npm el ecosistema para compartir código. En la práctica:

    • package.json declara las intenciones; package-lock.json registra los hechos. Guarda ambos archivos.
    • Nunca guardes node_modules.
    • Un rango de selección permite actualizaciones menores y de parche, y npm update se realiza dentro de ese rango.
    • Utiliza npm ci para instalaciones exactas en procesos automatizados.
    • Agrega dependencias de forma intencionada; cada una es código en el que confías.

    Así que la próxima vez que escribas:

    npm install
    

    recuerda que estás conectando tu proyecto a un ecosistema creado por desarrolladores de todo el mundo.

    Lecturas relacionadas