->Backward compatible new functionalities
->Large internal refactor
->Deprecation of old functionality (which is still operational)
->With the caret you can get releases like 3.., where the * characters will match the highest version number available. So changes in the major digit, like 4.0.0, will not be used in this case.
->With tilde, you can get releases like 3.9.*. Only the latest bug fixes are allowed with the tilde.
So we can conclude by saying that the ~ character should be used if you want to lock in the patch number. You should use this when you are ready to accept only bug-fixes and don't want to face any possibly incompatible alterations. On the other hand, the ^ character is responsible for locking in the patch and the minor version numbers. It's to be used when you want to have backwards compatible new functionality as well as bug fixes.