Guía9 min

engines.node para coding agents: lee package.json antes de nvm use

Resumen

El campo engines en package.json declara qué Node (y npm) acepta el repo. Por default npm solo avisa. pnpm puede fallar con engine-strict. Un agente que instala Node 22 en un repo de 18 rompe native addons. Esta guía cubre engines, .nvmrc y qué no inventar.

GitHub
package.json con engines.node y un agente leyendo la versión antes de instalar

Qué resuelve

Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.

Antes de nvm install 22 porque “Next 16 pide 20+”, el agente abre package.json. El campo engines es el contrato: { "node": ">=18.18.0", "pnpm": ">=9" }. Semver ranges, no un número suelto si el repo no lo pide.

npm Docs (package.json → engines): describe las versiones de node/npm con las que trabaja el paquete. No es un hard fail en npm salvo engine-strict=true. pnpm tiene engine-strict en .npmrc / settings: si está on, el install falla. El agente que ignora el warning y sigue, deja un node_modules con binarios de otra ABI.

No sustituye Corepack (packageManager). Eso pinnea pnpm; esto pinnea Node. El curso instalar un agente asume un Node ya bueno.

Orden de lectura

  1. package.jsonengines.node
  2. .nvmrc / .node-version / volta.node si existen
  3. packageManager (otra guía)
  4. Recién entonces, el Node del PATH (node -v)

Si 1 y 4 no matchean: para y reporta. No nvm use 24 “para ver si pasa”.

"engines": {
  "node": ">=20 <23",
  "pnpm": ">=9"
}

>=20 <23 no es “instala 22 latest”. En CI, actions/setup-node con node-version-file: '.nvmrc' o el range del campo. Un agente local: nvm use del .nvmrc si hay; si no, no cambies el Node del humano.

engines.node vs node -v

Flags

SitioDefaultSi el Node no cumple
npmwarningSigue
npm engine-strictoffFail
pnpm engine-strictoff (config)Fail si true
CI setup-nodeel que pongasEl job usa esa versión, ignore engines

El agente no pone engine-strict=false “para desbloquear”. Arregla la versión.

Native addons (better-sqlite3, sharp): un Node distinto recompila o crashea. pnpm install no es gratis si cambiaste Node a mitad.

Receta AGENTS.md

Read engines.node and .nvmrc first.
If node -v mismatches, stop. Do not nvm install latest.
Do not set engine-strict=false.
CI: setup-node from .nvmrc or engines.

CI setup-node desde .nvmrc

gitignore no cubre el binario de Node. Sandboxing tampoco.

FAQ

¿engines en una lib publicada? Aviso a consumidores. En una app, es el techo del equipo.

¿Volta? Si hay "volta": { "node": "20.11.0" } en package.json, esa gana para humanos con Volta. El agente sin Volta lee el número igual.

¿Bun? Si engines dice node, no asumas bun. Distinto runtime.

¿Subir engines en el PR? Solo si el ticket es upgrade. No de paso.

Si node -v es 18 y engines pide >=20, el síntoma suele ser un error críptico de sharp o de Next, no un mensaje de engines. Por eso el check es antes del install, no después del crash. Un node -v de una línea ahorra un rm -rf node_modules.

Verificado 2026-09-03 contra npm package.json#engines y pnpm engine-strict.