
Caret vs Tilde: What ^1.2.3 and ~1.2.3 Actually Allow (2026)
- VersionDude
- guides
- 7 min de leitura
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.
O versionamento semântico diz-lhe o que significa um número de lançamento. Não lhe diz que lançamentos o seu projeto aceitará da próxima vez que alguém correr uma instalação. Isso decide-o o **intervalo** que escreveu, e é na sintaxe dos intervalos que vivem quase todas as surpresas.
Dois caracteres fazem quase todo o trabalho: o **til** `~` e o **caret** `^`.
**O til permite alterações ao nível de patch.** Na notação da própria documentação do semver, `~1.2.3` significa `>=1.2.3 <1.3.0-0`. Aceita 1.2.4 e 1.2.9, não aceita 1.3.0. Escrito com menos partes alarga-se: `~1.2` equivale a `1.2.x`, e `~1` a `>=1.0.0 <2.0.0-0`.
**O caret permite tudo o que não altere o número diferente de zero mais à esquerda.** Para um lançamento normal isso significa que `^1.2.3` vale `>=1.2.3 <2.0.0-0`: todas as atualizações menores e de patch até à maior seguinte. É a predefinição do npm ao instalar um pacote, e por isso a maioria dos ficheiros de dependências está cheia de carets.
Até aqui, os dois parecem uma simples escolha entre prudente e permissivo. Depois desce-se abaixo da versão 1.0.0, e o caret muda em silêncio a sua própria regra.
**`^0.2.3` significa `>=0.2.3 <0.3.0-0`.** Não `<1.0.0`. Como o elemento diferente de zero mais à esquerda é agora o menor, o caret trata um incremento de menor como a alteração que quebra: num pacote 0.x, um caret comporta-se como um til.
**`^0.0.3` significa `>=0.0.3 <0.0.4-0`.** Ou seja, nenhuma atualização. Com os dois primeiros números a zero, o patch passa a ser o elemento diferente de zero mais à esquerda, e o caret prende-o a um único lançamento.
Não é uma esquisitice a contornar, é deliberado. O semver diz que um pacote 0.x não promete estabilidade alguma, por isso as ferramentas recusam-se a presumir uma compatibilidade que nunca foi dada. A consequência prática é a que conta: **o mesmo caret dá-lhe três níveis de liberdade diferentes consoante a numeração do pacote**, e um ficheiro de dependências cheio de carets não é uniformemente permissivo.
A segunda coisa a saber é que um intervalo é uma permissão, não uma decisão. O que é realmente instalado fica registado no ficheiro de bloqueio, e o intervalo apenas define para onde uma atualização pode ir. Uma equipa que lê o intervalo e esquece o lockfile acaba a depurar duas máquinas com duas versões diferentes que satisfazem ambas a mesma linha.
Para escolher, a regra honesta é curta. O caret para bibliotecas em que confia que respeitem o semver e que quer manter atualizadas. O til quando um incremento de menor já lhe saiu caro. A fixação exata quando realmente não pode absorver uma surpresa, aceitando que as atualizações passam a ser trabalho seu. E verifique aquilo em que um intervalo se expande antes de confiar nele, porque `^0.x` não significa o que esse mesmo símbolo significa uma versão maior adiante.


