After I upgraded to latest stable node
and npm
, I tried npm install moment --save
. It saves the entry in the package.json
with the caret(^)
prefix. Previously, it was a tilde(~)
prefix.
- Why are these changes made in
npm
? - What is the difference between
tilde(~)
andcaret(^)
? - What is the advantages over others?
http://fredkschott.com/post/2014/02/npm-no-longer-defaults-to-tildes/
Note that the author's terminology is somewhat misleading: when he says "the most recent minor version" for ~ he means "the most recent patch version in the specified minor version". Similarly for ^, "the most recent major version" should be read as "the most recent minor version in the specified major version".
I would like to add the official npmjs documentation as well which describes all methods for version specificity including the ones referred to in the question -
https://docs.npmjs.com/files/package.json
https://docs.npmjs.com/misc/semver#x-ranges-12x-1x-12-
~version
"Approximately equivalent to version" See npm semver - Tilde Ranges & semver (7)^version
"Compatible with version" See npm semver - Caret Ranges & semver (7)version
Must match version exactly>version
Must be greater than version>=version
etc<version
<=version
1.2.x
1.2.0, 1.2.1, etc., but not 1.3.0http://sometarballurl
(this may be the URL of a tarball which will be downloaded and installed locally*
Matches any versionlatest
Obtains latest releaseThe above list is not exhaustive. Other version specifiers include GitHub urls and GitHub user repo's, local paths and packages with specific npm tags
Hat matching may be considered "broken" because it wont update
^0.1.2
to0.2.0
. When the software is emerging use0.x.y
versions and hat matching will only match the last varying digit (y
). This is done on purpose. The reason is that while the software is evolving the API changes rapidly: one day you have these methods and the other day you have those methods and the old ones are gone. If you don't want to break the code for people who already are using your library you go and increment the major version: e.g.1.0.0
->2.0.0
->3.0.0
. So, by the time your software is finally 100% done and full-featured it will be like version11.0.0
and that doesn't look very meaningful, and actually looks confusing. If you were, on the other hand, using0.1.x
->0.2.x
->0.3.x
versions then by the time the software is finally 100% done and full-featured it is released as version1.0.0
and it means "This release is a long-term service one, you can proceed and use this version of the library in your production code, and the author won't change everything tomorrow, or next month, and he won't abandon the package".The rule is: use
0.x.y
versioning when your software hasn't yet matured and release it with incrementing the middle digit when your public API changes (therefore people having^0.1.0
won't get0.2.0
update and it won't break their code). Then, when the software matures, release it under1.0.0
and increment the leftmost digit each time your public API changes (therefore people having^1.0.0
won't get2.0.0
update and it won't break their code).^
is 1.[any].[any] (latest minor version)~
is 1.2.[any] (latest patch)A great read is this blog post on how semver applies to npm
and what they're doing to make it match the semver standard
http://blog.npmjs.org/post/98131109725/npm-2-0-0
~ Tilde:
~
fixes major and minor numbers.^ Caret:
^
fixes the major number only.~
fixes major and minor numbers. It is used when you're ready to accept bug-fixes in your dependency, but don't want any potentially incompatible changes.^
fixes the major number only. It is used when you're closely watching your dependencies and are ready to quickly change your code if minor release will be incompatible.In addition to that,
^
is not supported by old npm versions, and should be used with caution.So,
^
is a good default, but it's not perfect. I suggest to carefully pick and configure the semver operator that is most useful to you.