Skip to content

npm y package.json ​

npm es el gestor de paquetes de Node y el registro de software más grande del mundo. En esta lección aprenderás a crear proyectos, instalar dependencias, entender las versiones y automatizar tareas con scripts.

Concepto ​

  • Paquete: código que alguien publicó para que otros lo reutilicen (Express, zod, dayjs...).
  • package.json: la "ficha técnica" de tu proyecto: nombre, dependencias, scripts.
  • node_modules/: carpeta donde se descargan los paquetes. Nunca se sube a Git.
  • package-lock.json: registra las versiones exactas instaladas para que todo el equipo tenga lo mismo. Sí se sube a Git.

Analogía: package.json es tu lista de compras ("leche, cualquier marca entera"); package-lock.json es el ticket exacto ("Leche Lala 1L, lote 123").

Crear un proyecto ​

bash
mkdir mi-api && cd mi-api
npm init -y

Genera un package.json básico. Ajústalo así para un proyecto moderno:

json
{
  "name": "mi-api",
  "version": "1.0.0",
  "description": "API de ejemplo",
  "type": "module",
  "main": "src/index.js",
  "scripts": {
    "dev": "node --watch src/index.js",
    "start": "node src/index.js"
  },
  "engines": {
    "node": ">=22"
  },
  "license": "MIT"
}

Instalar dependencias ​

bash
# Dependencia de producción (la app la necesita para funcionar)
npm install express
npm i zod            # "i" es atajo de install

# Dependencia de desarrollo (sólo para programar/probar)
npm install -D vitest prettier

# Versión específica
npm i express@5.1.0

# Instalar todo lo del package.json (al clonar un proyecto)
npm install

# Instalación limpia y exacta (CI y producción)
npm ci

# Desinstalar
npm uninstall dayjs

Tu package.json queda así:

json
{
  "dependencies": {
    "express": "^5.1.0",
    "zod": "^4.1.0"
  },
  "devDependencies": {
    "prettier": "^3.6.0",
    "vitest": "^3.2.0"
  }
}

Versionado semántico (SemVer) ​

Las versiones tienen formato MAYOR.MENOR.PARCHE, por ejemplo 5.1.3:

ParteCuándo cambia¿Rompe tu código?
MAYOR (5)Cambios incompatiblesPuede que sí
MENOR (1)Funciones nuevas compatiblesNo
PARCHE (3)Corrección de erroresNo

Símbolos en package.json:

RangoSignificaAcepta
^5.1.3Mismo MAYOR5.1.3 a < 6.0.0
~5.1.3Mismo MENOR5.1.3 a < 5.2.0
5.1.3ExactaSólo 5.1.3
* o latestCualquiera⚠️ Peligroso

Scripts ​

Los scripts automatizan tareas. Se ejecutan con npm run nombre (y npm start / npm test sin run).

json
{
  "scripts": {
    "dev": "node --watch --env-file=.env src/index.js",
    "start": "node src/index.js",
    "test": "vitest run",
    "test:watch": "vitest",
    "format": "prettier --write .",
    "lint": "eslint .",
    "db:migrate": "prisma migrate dev",
    "predev": "echo Iniciando entorno de desarrollo...",
    "check": "npm run lint && npm test"
  }
}
  • Los scripts pueden usar los binarios de node_modules/.bin directamente (vitest, prettier) sin instalarlos globalmente.
  • pre<nombre> y post<nombre> se ejecutan antes/después automáticamente.
  • && encadena comandos: el segundo sólo corre si el primero tuvo éxito.
bash
npm run dev
npm test
npm run check

Pasar argumentos a un script ​

bash
npm test -- --reporter=verbose

Todo lo que va después de -- se pasa al comando.

npx ​

Ejecuta un paquete sin instalarlo en tu proyecto:

bash
npx create-vite@latest mi-frontend
npx prisma init
npx serve dist

Comandos de mantenimiento ​

bash
npm outdated         # qué paquetes tienen versiones nuevas
npm update           # actualiza dentro de los rangos permitidos
npm audit            # busca vulnerabilidades conocidas
npm audit fix        # intenta corregirlas
npm ls express       # qué versión está instalada y quién la usa
npm view zod versions --json   # versiones publicadas

.gitignore ​

txt
node_modules/
.env
dist/
coverage/
*.log

Caso real: un paquete en acción ​

bash
mkdir fechas && cd fechas
npm init -y
npm pkg set type=module
npm i dayjs
js
// index.js
import dayjs from 'dayjs'
import 'dayjs/locale/es-mx.js'
import relativeTime from 'dayjs/plugin/relativeTime.js'

dayjs.locale('es-mx')
dayjs.extend(relativeTime)

const entrega = dayjs().add(3, 'day')
console.log('Hoy:', dayjs().format('dddd D [de] MMMM [de] YYYY'))
console.log('Entrega:', entrega.format('DD/MM/YYYY'))
console.log('Entrega', entrega.fromNow())   // "en 3 días"
bash
node index.js

Buena práctica

  • Sube package-lock.json a Git y usa npm ci en servidores y CI.
  • Antes de instalar un paquete, revisa en npmjs.com sus descargas semanales, fecha de última publicación y repositorio. Menos dependencias = menos riesgo.
  • Nunca instales paquetes globales para un proyecto: usa devDependencies + scripts.

Error común

Subir node_modules a Git. Pesa cientos de MB y depende del sistema operativo. Si ya lo subiste: agrégalo a .gitignore y ejecuta git rm -r --cached node_modules.

Seguridad

Existen paquetes maliciosos con nombres parecidos a los populares (typosquatting): expres, lodahs. Revisa bien el nombre antes de instalar.

Ejercicios ​

  1. Crea un proyecto con scripts dev, start y saludo (este último imprime "Hola desde npm" con node -e).
  2. Instala chalk y escribe un script que imprima "Éxito" en verde y "Error" en rojo.
  3. ¿Qué versiones acepta ~4.17.1? ¿Y ^0.3.2?
Ver solución
json
{
  "name": "ejercicio",
  "type": "module",
  "scripts": {
    "dev": "node --watch index.js",
    "start": "node index.js",
    "saludo": "node -e \"console.log('Hola desde npm')\""
  },
  "dependencies": {
    "chalk": "^5.4.0"
  }
}
js
// index.js
import chalk from 'chalk'

console.log(chalk.green('Éxito'))
console.log(chalk.red.bold('Error'))
  1. ~4.17.1 acepta de 4.17.1 hasta antes de 4.18.0. ^0.3.2 acepta de 0.3.2 hasta antes de 0.4.0: con MAYOR en 0, el ^ se comporta como ~, porque en versiones 0.x cada MENOR puede romper compatibilidad.

Resumen ​

  • npm init -y crea package.json; npm i instala; -D para desarrollo.
  • package-lock.json fija versiones exactas: súbelo a Git; node_modules no.
  • SemVer: MAYOR.MENOR.PARCHE; ^ permite menores y parches.
  • Los scripts (npm run x) automatizan desarrollo, pruebas y despliegue.

Academia Web — aprende, copia y construye.