Logotipo de Bitdoze

Actualizar Paquetes con Bun: Cómo Actualizar a la Última Versión

Actualiza paquetes con Bun a la última versión: ejecuta bun update, bun update --latest, o el interactivo bun update -i. Mira cómo se reescriben package.json y bun.lock.

Dragos

Actualizado Publicado 23 min de lectura

Actualizar Paquetes con Bun: Cómo Actualizar a la Última Versión

La forma más rápida de actualizar paquetes a la última versión con Bun es bun update. Desde Bun 1.2 también reescribe package.json y bun.lock por ti, que es la parte que la mayoría de guías sigue haciendo mal. Si recuerdas una cosa de este post, que sea esta: revisa git diff tras cada actualización, porque Bun tocará tu manifiesto.

Bun está en 1.4.x ahora (el proyecto se movió de bun.sh a bun.com), y su gestor de paquetes cubre todo el flujo de actualización sin herramientas extra. Puedes actualizar todo dentro del rango, elegir paquetes interactivamente con bun update -i, saltar majors con bun update --latest, o parchear una sola dependencia transitiva. Son los mismos paquetes Node.js que gestiona npm. Bun solo los instala y actualiza más rápido. Si aún necesitas un runtime Node junto a Bun, mira cómo instalar Node.js con NVM en macOS y Ubuntu.

El flujo de abajo es el que uso: actualiza el propio Bun, comprueba qué está desactualizado, actualiza, verifica, y haz rollback si el build se rompe. ¿Nuevo en Bun? Empieza con la guía del gestor de paquetes Bun vs NPM, Yarn y PNPM. ¿Moviendo un sitio Astro? Mira cómo migrar Astro a Bun en Cloudflare Pages.

Actualización 2026

El vídeo de abajo se grabó en Bun 1.0.x. El flujo nativo bun update -i y bun update --latest de este post reemplaza el workaround de npm-check-updates mostrado en el vídeo. Los comandos de la guía escrita son los actuales.

Prerequisitos y flujo de actualización de un vistazo

Antes de tocar paquetes, asegúrate de tener lo básico en su sitio. Es una póliza de seguro de cinco minutos que te ahorra una tarde cuando una subida major rompe el build.

  • Bun instalado y razonablemente actual (bun --version, objetivo 1.4.x)
  • Un proyecto con package.json y un lockfile (bun.lock, o el viejo bun.lockb)
  • Un árbol git limpio, o al menos copias de package.json y bun.lock
  • Tu comando de test/build conocido de antemano (bun run build, bun test, lo que corra CI)

Commitea primero

Cada comando de abajo reescribe package.json y/o bun.lock. Un árbol git limpio es tu botón de deshacer: git restore package.json bun.lock && bun install te devuelve en segundos. Sin eso, el rollback es manual y miserable.

El flujo completo, en orden:

Quieres Ejecuta
Obtener el Bun más nuevo bun upgrade
Ver qué está desactualizado bun outdated
Subir todo dentro de tus rangos declarados bun update
Elegir paquetes tú mismo bun update -i
Cruzar versiones major bun update --latest
Actualizar un paquete bun update zod
Actualizar herramientas instaladas globalmente bun update -g

Usa esa tabla como hoja de ruta. Todo lo de abajo expande una fila con pasos de verificación y modos de fallo.

Actualiza primero el propio Bun a la última versión

Bun desactualizado, comportamiento desactualizado. Los flags de actualización y el formato del lockfile han cambiado a lo largo de 1.1, 1.2, 1.3 y 1.4, así que corre esto primero. Cómo actualizas depende de cómo se instaló Bun:

curl / script de instalación

bash
bun upgrade

Esta es la ruta por defecto del script de instalación oficial. Descarga el último build estable y reemplaza el binario.

¿Quieres el bleeding edge o un canal fijado en su lugar? bun upgrade --canary obtiene el build de desarrollo, bun upgrade --stable te devuelve a estable.

Homebrew

bash
brew upgrade bun

Scoop

bash
scoop update bun

No mezcles métodos de actualización

Si Bun se instaló con Homebrew o Scoop, no corras bun upgrade encima. El gestor de paquetes posee el binario y peleará contigo: deriva de versiones, errores de checksum, o un bun que reaparece como la versión brew en el próximo brew upgrade. Usa brew upgrade bun / scoop update bun y sé consistente. Mira los docs oficiales de instalación para la matriz completa.

Verifica: bun --version debería imprimir 1.4.x. Si el número no se movió, actualizaste una instalación distinta a la de tu PATH. Corre which bun (o where bun en Windows) y compáralo con dónde puso su copia tu gestor de paquetes.

Comprueba paquetes desactualizados con bun outdated

Corre esto antes de cada sesión de actualización. bun outdated (desde Bun 1.1.26) imprime una tabla con tres columnas de versión:

  • Current - lo que está en tu lockfile ahora mismo
  • Update - la versión más alta dentro de tu rango declarado
  • Latest - la versión publicada más nueva, majors incluidas

La diferencia entre las dos últimas columnas te dice qué comando necesitas realmente. Si todo lo que te importa está en la columna Update, bun update a pelo basta. Si las versiones que quieres están en Latest, estás ante una corrida de --latest (o una elección interactiva).

bash
bun outdated

La salida tiene esta forma (las versiones diferirán en tu proyecto):

text
Package          Current   Update   Latest
ms               2.1.0     2.1.3    2.1.3
zod              3.22.4    3.25.0   4.1.12
typescript       5.4.5     5.9.2    5.9.2

Filtros útiles:

bash
bun outdated '@types/*'      # glob: just the @types scope
bun outdated '!@types/*'     # negation: everything except @types
bun outdated -r              # every workspace in a monorepo
bun outdated --filter web    # one workspace

Verifica: cuando todo está al día, bun outdated imprime solo la cabecera y sale con 0. Esa es tu señal de “nada que hacer”. No-cero o una tabla llena significa que hay trabajo. Referencia: docs de bun outdated, notas de la versión v1.1.26.

Lee las columnas antes de actualizar

La división Update vs Latest es toda la decisión. Las subidas dentro de rango son baratas y aburridas. Las subidas cross-major son una rama, una corrida de CI y una lectura de changelog. No dejes que un único comando decida por ti.

Actualiza todos los paquetes con bun update (dentro de rango)

bun update a pelo (alias: bun up) sube tus dependencias directas y transitivas dentro de los rangos ya declarados en package.json. Una dependencia ^2.1.0 puede aterrizar en 2.1.3 o 2.9.9, nunca en 3.0.0.

bash
bun update

Previsualiza primero si quieres una vista en seco de lo que se movería:

bash
bun update --dry-run

Corrección (2026)

Las versiones viejas de esta guía decían que bun update deja package.json en paz. Eso no es cierto desde Bun ~1.2. Un bun update a pelo reescribe el suelo del rango para tus dependencias directas y actualiza bun.lock para coincidir. Fíate de git diff, no de la memoria.

Concretamente, esto:

json
"dependencies": {
  "ms": "^2.1.0"
}

se convierte en esto después de que bun update recoja 2.1.3:

json
"dependencies": {
  "ms": "^2.1.3"
}

El operador se preserva: ^ sigue siendo ^, ~ sigue siendo ~. Los fijados exactos (2.1.0) y los dist-tags (latest) se dejan como están escritos. Las dependencias transitivas también se mueven, y el lockfile registra cada cambio.

Verifica:

bash
git diff package.json bun.lock

Deberías ver solo las subidas que esperabas. Si package.json muestra un diff en una dependencia que creías fijada, ese fijado probablemente era un rango después de todo.

Cómo se ve “roto”: ninguna salida en absoluto significa que nada estaba fuera de rango (o nada está instalado aún - corre bun install primero). Un muro de churn en bun.lock sin cambio en package.json es normal tras movimientos de metadatos del registry. Los docs: bun update.

Actualiza paquetes a la última versión con bun update --latest

Este es el flag que la gente realmente quiere cuando dice “actualiza todo a lo más nuevo”. --latest (corto: -L) ignora tus rangos declarados para las dependencias directas, instala las versiones publicadas más nuevas incluyendo majors, y reescribe package.json para coincidir.

bash
bun update --latest

Todo recibe el tratamiento cross-major:

bash
bun update --latest
# zod 3.22.4  ->  4.1.12   (major)
# typescript 5.4.5 -> 5.9.2 (same major, but outside your ^5.4 range floor rewrite)

Cómo funciona la reescritura: tu "zod": "^3.22.4" se convierte en "zod": "^4.1.12" - mismo estilo de rango, nuevo suelo. Las dependencias transitivas siguen respetando los rangos de sus dependientes, y Bun nunca degrada una dependencia que ya está por delante de latest (instalaciones prerelease). Disponible desde Bun 1.2 (notas de versión).

--force vs --latest: por qué --force no actualiza a latest

--force no es --latest

bun update --force significa “solicita siempre las últimas versiones del registry y reinstala todas las dependencias”. Es un refresco de caché y metadatos. No evita tus rangos semver. Si bun update --force parece “no actualizar” paquetes, lo que querías era bun update --latest.

Los dos comandos lado a lado:

bash
bun update --force    # refresh registry metadata, reinstall what your ranges allow
bun update --latest   # cross majors, rewrite package.json to the newest versions

Actualiza solo dependencias de producción o de desarrollo

bash
bun update --prod       # or -P: dependencies only
bun update --dev        # or -D: devDependencies only
bun update --no-optional

Combina libremente: bun update --dev --latest es el movimiento habitual de “lleva las herramientas de dev a los majors, deja las deps de runtime en paz”.

Patrones glob y exclusiones

bash
bun update '@types/*' --latest     # all @types packages to their latest
bun update '!@babel/core' --latest # everything except @babel/core
bun update jquery@3                # move jquery within the 3.x line

Nota de ops: los majors rompen builds. Trata --latest como un evento de rama-más-CI, no un comando de viernes a las 17:00. Tras aterrizar los majors y tener CI en verde, redespliega y haz smoke-test en producción. Para sitios Astro, mira cómo desplegar un blog Astro en Cloudflare.

Despliega tu sitio Astro actualizado en Cloudflare

Elige paquetes interactivamente con bun update -i

Desde Bun 1.3, el selector interactivo está integrado. Esto reemplaza el workaround bunx npm-check-updates -ui que esta guía solía recomendar.

bash
bun update -i

Obtienes una lista de dependencias directas desactualizadas agrupadas por dependencies, devDependencies, peer y optional, con columnas Current, Target y Latest. Target es la subida dentro de rango, Latest es la publicada más nueva. Código de color: rojo para major, amarillo para minor, verde para patch.

Teclas que vale la pena conocer:

Tecla Acción
Space Alterna el paquete resaltado
a Alterna todos
n No selecciona ninguno
i Invierte la selección
l Cambia la fila resaltada entre target y latest
Enter Aplica
Ctrl+C Cancela sin cambios

La tecla l es la que la gente se pierde. Te permite llevar la mayoría de paquetes dentro de rango y empujar uno solo arriesgado hasta latest, en una pasada. (Notas de Bun 1.3.)

Cambio de comportamiento en 1.4: -i necesita un terminal real

Desde Bun 1.4.0, bun update -i con un stdin no-TTY sale con código 1 en vez de abrir el selector. Eso significa que no funcionará en scripts de CI o entrada por pipe. Córrelo interactivamente, o usa bun update --latest / bun update pkg dirigido en automatización. (Notas de Bun 1.4.)

Ya no necesitas npm-check-updates

bun update -i y bun update --latest cubren el viejo flujo ncu de forma nativa. Si quieres subidas por etapas en su lugar - por ejemplo, solo minors durante un tiempo - ncu sigue haciéndolo bien:

bash
bunx npm-check-updates -t minor -u

Eso actualiza package.json solo a las versiones minor más nuevas. Mira npm-check-updates si lo necesitas.

Verifica: como siempre, git diff package.json bun.lock, luego tu build.

Actualizaciones dirigidas: paquetes únicos, globs y deps transitivas

Raramente necesitas “todo o nada”. Las actualizaciones por nombre manejan los casos quirúrgicos:

bash
bun update zod           # zod everywhere it appears, including transitively
bun update caniuse-lite  # patch a nested/transitive dep
bun update '@types/*'    # glob

Dos detalles que cambiaron en Bun 1.4 e importan en proyectos reales (notas de versión):

  1. bun update pkg ahora actualiza ese paquete en todos los sitios donde aparece, incluyendo ocurrencias transitivas, no solo la entrada de nivel superior. Eso es lo que quieres para una corrección de seguridad enterrada tres niveles abajo.
  2. Las dependencias de catálogo (catalog: en workspaces) también se reescriben.

Una actualización dirigida de un paquete que no está en tu package.json - el caso caniuse-lite - arregla el lockfile sin añadir una dependencia a tu manifiesto. Esa es la herramienta correcta para “mi dep transitiva tiene un advisory y no puedo esperar a que suba el padre”.

Monorepos: --recursive y --filter

bash
bun outdated -r                  # all workspaces
bun update -r                    # update every workspace
bun update --filter web          # just the web workspace
bun update -r --latest           # cross majors everywhere (careful)

Tras una gran pasada multi-workspace, limpia:

bash
bun dedupe     # collapse duplicate versions in the lockfile
bun prune      # drop packages not in package.json (new in 1.4)
  • Una dependencia necesita un fix → bun update pkg
  • Todo debería moverse dentro de rangos → bun update
  • Quieres majors → bun update --latest
  • Quieres elegir, fila a fila → bun update -i
  • CI o un script → comandos dirigidos o --latest, nunca -i

Actualiza paquetes globales con bun update -g

Las herramientas globales son una historia aparte de las dependencias del proyecto. Nada aquí toca el package.json de ningún proyecto.

Todas las globales

bash
bun update -g

Una global

bash
bun update -g typescript

Fijar a latest

bash
bun add -g typescript@latest

Las globales viven en ~/.bun/install/global. Un bun add -g pkg fresco a veces es más limpio que una actualización cuando una herramienta cambió su layout de bin entre majors.

Modos de fallo: “command not found” tras una actualización global normalmente significa que el directorio shim falta en tu PATH (~/.bun/bin). Y recuerda que el proyecto gana: si un proyecto tiene una instalación local de la misma herramienta, bun run usa la local aunque exista una global más nueva.

Cómo reescribe bun update package.json y bun.lock

Esta es la sección para la búsqueda “bun update package.json”. La mecánica es simple una vez vista:

  • Actualización dentro de rango sube el suelo del rango y preserva el operador. ^1.1.0 se convierte en ^1.2.0, ~1.1.0 se convierte en ~1.1.5. Nada cruza un major.
  • --latest reescribe cruzando majors a un rango del mismo estilo: ^1.1.0 se convierte en ^2.0.0 si 2.0.0 es lo más nuevo.
  • Fijados exactos y dist-tags se quedan como están escritos salvo que pases --latest.
  • --no-save actualiza solo node_modules. package.json y el lockfile no se mueven. Útil para un experimento local rápido que piensas revertir.

En el lado del lockfile: el bun.lock basado en texto reemplazó al binario bun.lockb en Bun 1.2, y Bun automigra el formato viejo. Desde 1.3 también migra yarn.lock y pnpm-lock.yaml al instalar, así que mover un proyecto a Bun no significa escribir un lockfile a mano.

Antes y después, todo el cambio puede verse así:

diff
-    "ms": "^2.1.0"
+    "ms": "^2.1.3"

Diff, no volcado

git diff package.json es la forma honesta de ver qué cambió. Pegar un package.json entero en una ventana de chat para averiguar qué se movió es cómo la gente pierde la pista de los fijados.

Si necesitas subidas por etapas - toma los minors ahora, los majors el próximo sprint - ese es el único caso de uso que queda para npm-check-updates:

bash
bunx npm-check-updates -t minor -u

Actualizaciones por seguridad: bun audit y bun audit fix

Las actualizaciones de dependencias no son solo por funciones. bun audit lista advisories conocidos contra tu árbol:

bash
bun audit

Desde Bun 1.4.0, puedes actuar sobre el informe directamente (notas de versión):

bash
bun audit fix --dry-run   # preview first
bun audit fix             # upgrade vulnerable packages to safe versions
bun audit fix --latest    # allow major jumps when the fix requires one

Eso elimina el viejo bucle de “audit, abre el advisory, edita rangos a mano” para la mayoría de casos.

Dos notas de hardening sobre las que vale actuar:

  1. Retén los paquetes recién publicados. Bun soporta una antigüedad mínima de release, así que una versión secuestrada o maliciosa recién publicada nunca se instala el día cero:
ini
# bunfig.toml
[install]
minimumReleaseAge = 604800   # 7 days, in seconds

El equivalente CLI es --minimum-release-age. (Notas de Bun 1.3.)

  1. Los paquetes parcheados son retenidos por bun update. Si usaste bun patch y tienes patchedDependencies, una actualización normal no moverá ese paquete - descartaría silenciosamente tu parche. --latest y bun audit fix sí lo moverán, lo que significa que necesitas recrear el parche después.

Re-parchea tras mover una dependencia parcheada

bun update --latest o bun audit fix sube un paquete parcheado: tu parche ya no aplica, y patchedDependencies fallará en el próximo install hasta que rehagas bun patch contra la nueva versión. Presupuesta cinco minutos por paquete parcheado.

Cadencia de ops: nada de esto cuesta dinero. La herramienta es Bun más el registry público de npm. Lo que paga es el hábito: un bun outdated -r && bun update semanal, o Dependabot/Renovate en el repo con bun.lock en el commit. Actualizaciones pequeñas y frecuentes son un trabajo de un café. Las actualizaciones anuales son un incidente.

Verifica la actualización y haz rollback si hace falta

Una actualización que no has verificado es solo un lockfile modificado. Cuatro pasos, cada vez:

  • git diff package.json bun.lock - mira qué se movió realmente
  • bun install --frozen-lockfile - prueba que el lockfile es completo y reproducible (el mismo check que CI debería correr)
  • bun run build y bun test si tienes tests
  • Smoke-test de la app: servidor dev o preview, recorre la ruta crítica

Si te importa el tiempo de build - y tras una subida de dependencias correrás builds más de lo normal - mira nuestro benchmark de builds de Astro 7. Una vez el build está en verde otra vez, la optimización de velocidad de build de Astro es el siguiente paso que paga en cada ciclo de actualización posterior.

Rollback

Como commiteaste primero:

bash
git restore package.json bun.lock
bun install

Si estás a mitad de rama y quieres revertir una sola dependencia en vez de toda la pasada:

bash
bun update zod@3.22.4     # pin back to the old version

¿Sin git? Guarda copias de package.json y bun.lock antes de empezar. Esa es toda la estrategia de backup; no hay estado oculto en ningún otro sitio.

Modos de fallo comunes tras una gran actualización

  1. El build se rompe en un major. Revierte esa dependencia (bun update pkg@1.2.3) o fíjala y agenda la migración. No apiles un segundo --latest encima de un build en rojo.
  2. CI falla por desajuste de lockfile. package.json y bun.lock deben commitearse juntos. Un bun install --frozen-lockfile en CI rechazará un lockfile que no coincide con el manifiesto.
  3. El build muere con OOM en un VPS pequeño. No es un bug de dependencias: añade swap, buildea en otro sitio, o baja el paralelismo. Las máquinas de 1-2 GB se quedan sin heap durante builds de Astro/Next tras actualizaciones pesadas de devDependencies.
  4. Errores de patchedDependencies tras la actualización. Re-corre bun patch contra la nueva versión del paquete, o suelta el parche si upstream lo arregló.

Nota de coste/ops: las actualizaciones son gratis. Los despliegues rotos no. Corre esto en una rama, deja que CI lo buildee, luego mergea. Diez minutos de pipeline le ganan a un rollback en producción.

FAQ: actualizar paquetes con Bun

¿bun update cambia package.json?

Sí. Un bun update a pelo reescribe los rangos de versión de tus dependencias directas dentro de sus límites declarados (^2.1.0 se convierte en ^2.1.3) y actualiza bun.lock. bun update --latest va más allá y reescribe rangos cruzando majors. Solo --no-save deja ambos archivos intactos.

bash
git diff package.json bun.lock   # always check after updating
¿Cuál es la diferencia entre bun update y bun update --latest?

bun update se queda dentro de los rangos ya presentes en package.json: sin majors, solo las versiones más nuevas que tu manifiesto permite. bun update --latest (o -L) ignora esos rangos para las dependencias directas, instala las versiones publicadas más nuevas incluyendo majors, y reescribe package.json para coincidir.

bash
bun update           # in-range
bun update --latest  # cross-major
¿Cómo actualizo el propio Bun?

Corre bun upgrade si instalaste Bun con el script oficial, brew upgrade bun en Homebrew, o scoop update bun en Scoop. Luego confirma con bun --version - debería mostrar 1.4.x.

bash
bun upgrade && bun --version
¿Cómo actualizo paquetes globales con Bun?

bun update -g actualiza todos los paquetes globales, bun update -g pkg actualiza uno, y bun add -g pkg@latest fija una instalación global a la versión más nueva. Las globales viven en ~/.bun/install/global y el package.json de ningún proyecto se ve afectado.

bash
bun update -g
¿bun update --force es lo mismo que actualizar a la última versión?

No. --force significa “solicita siempre las últimas versiones del registry y reinstala todas las dependencias”. Refresca metadatos cacheados y reinstala lo que tus rangos ya permiten. Para cruzar versiones major y obtener los paquetes publicados más nuevos, usa bun update --latest.

bash
bun update --latest   # the one you wanted

Conclusiones

El flujo 2026 es corto: bun upgrade, bun outdated, luego bun update / bun update -i / bun update --latest dependiendo de cuánto churn quieras. Verifica con git diff y bun install --frozen-lockfile, y haz rollback con git restore package.json bun.lock && bun install cuando el build se queje.

Dos correcciones a consejos antiguos que vale la pena mantener: bun update sí reescribe package.json, y --force no es el flag de “dame las últimas versiones” - lo es --latest. Con eso claro, las herramientas integradas de Bun cubren todo el trabajo de actualización sin npm-check-updates ni ningún otro wrapper.

Si estás empezando un proyecto desde cero, crea un blog Astro gratis en Cloudflare y corre este bucle de actualización en él desde el día uno.

Crea un blog Astro gratis en Cloudflare