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.

[code]
~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.*
[/code]

The caret operator follows Semver.

[code]

^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.*
[/code]

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.

[code]
// 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
[/code]

A workaround for this could be that you always specify versions under 1.0.0 with an asterisk ("*").

[code]
0.2.* means >=0.2.0 <0.3.0
[/code]

A better approach is to continue to use the caret operator as it still respects Semver even on versions under 1.0.0.

[code]
^0.2 means >=0.2.0 <0.3.0
[/code]

In conclusion: One should always use caret ("^") over tilde ("~") because caret is always respecting Semver.