I've been noticing people having trouble understanding the differences between the caret ("^") and the tilde ("~") operator in the composer.json file. Composer's documentation is great but a bit short, that is why I write this blog post.
Composer assumes that all packages are using Semver. It is an easy version schema that consists of a major.minor.patch version. A major version breaks backwards compatibility, minor version introduces new features and patch versions are bug fixes.
The tilde operator is best explained by example. Notice that it actually makes a difference if you specify the patch version or not.
~1.0 means >=1.0.0 <2.0.0 same as 1.*
~1.0.0 means >=1.0.0 <1.1.0 same as 1.0.*
The caret operator follows Semver.
^1.0 means >=1.0.0 <2.0.0 same as 1.*
^1.0.0 means >=1.0.0 <2.0.0 same as 1.*
What is little less known is that Semver behaves differently on versions under 1.0.0. Before the project has a stable release, minor versions are allowed to break backwards compatibility. This is dangerous when you use the tilde operator since you may get update that breaks backwards compatibility.
// This is dangerous as updates might break BC
~0.2 means >=0.2.0 <1.0.0
// This is fine
~1.2 means >=1.2.0 <2.0.0
A workaround for this could be that you always specify versions under 1.0.0 with an asterisk ("*").
0.2.* means >=0.2.0 <0.3.0
A better approach is to continue to use the caret operator as it still respects Semver even on versions under 1.0.0.
^0.2 means >=0.2.0 <0.3.0
In conclusion: One should always use caret ("^") over tilde ("~") because caret is always respecting Semver.