Caret vs Tilde: What ^1.2.3 and ~1.2.3 Actually Allow (2026)

  • VersionDude
  • guides
  • 7 min de lectura

Semantic versioning explains what a version number means. The range syntax decides which versions you accept without asking. The two are not the same, and the caret changes its own rules below 1.0.0.

El versionado semántico te dice qué significa un número de publicación. No te dice qué publicaciones aceptará tu proyecto la próxima vez que alguien ejecute una instalación. Eso lo decide el **rango** que escribiste, y es en la sintaxis de rangos donde viven casi todas las sorpresas.

Dos caracteres hacen casi todo el trabajo: la **tilde** `~` y el **caret** `^`.

**La tilde permite cambios de nivel patch.** En la notación de la propia documentación de semver, `~1.2.3` significa `>=1.2.3 <1.3.0-0`. Aceptas 1.2.4 y 1.2.9, no aceptas 1.3.0. Escrita con menos partes se ensancha: `~1.2` equivale a `1.2.x`, y `~1` a `>=1.0.0 <2.0.0-0`.

**El caret permite todo lo que no modifique el número distinto de cero más a la izquierda.** Para una publicación normal eso significa que `^1.2.3` es `>=1.2.3 <2.0.0-0`: todas las actualizaciones menores y de parche hasta la siguiente mayor. Es el valor por defecto de npm al instalar un paquete, por eso la mayoría de ficheros de dependencias están llenos de carets.

Hasta aquí, ambos parecen una simple elección entre prudente y permisivo. Luego bajas de la versión 1.0.0, y el caret cambia en silencio su propia regla.

**`^0.2.3` significa `>=0.2.3 <0.3.0-0`.** No `<1.0.0`. Como el elemento distinto de cero más a la izquierda es ahora el menor, el caret trata una subida de menor como el cambio rompedor: en un paquete 0.x, un caret se comporta como una tilde.

**`^0.0.3` significa `>=0.0.3 <0.0.4-0`.** Es decir, ninguna actualización. Con los dos primeros números a cero, el parche pasa a ser el elemento distinto de cero más a la izquierda, y el caret te fija a una única publicación.

No es una rareza que haya que sortear, es deliberado. Semver dice que un paquete 0.x no promete estabilidad alguna, así que las herramientas se niegan a suponer una compatibilidad que nunca se les dio. La consecuencia práctica es la que importa: **el mismo caret te da tres niveles de libertad distintos según cómo esté numerado el paquete**, y un fichero de dependencias lleno de carets no es uniformemente permisivo.

Lo segundo que conviene saber es que un rango es un permiso, no una decisión. Lo que realmente se instala queda registrado en el fichero de bloqueo, y el rango solo define hacia dónde puede moverse una actualización. Un equipo que lee el rango y olvida el lockfile acaba depurando dos máquinas con dos versiones distintas que satisfacen ambas la misma línea.

Para elegir, la regla honesta es corta. El caret para bibliotecas que crees que respetan semver y quieres mantener al día. La tilde cuando una subida de menor ya te ha costado caro. La fijación exacta cuando de verdad no puedes absorber una sorpresa, asumiendo que las actualizaciones pasan a ser tu trabajo. Y comprueba a qué se expande un rango antes de fiarte, porque `^0.x` no significa lo que ese mismo símbolo significa una versión mayor más adelante.

Proyecto relacionado