Given a version number MAJOR.MINOR.PATCH, increment the: 1. MAJOR version when you make incompatible API changes,

2. MINOR version when you add functionality in a backwards-compatible manner, and

3. PATCH version when you make backwards-compatible bug fixes.

But what is incompatible, and backwards compatible? What is a bugfix? Minor version is quite clear: if you add a new feature, without changing existing code, then it’s a minor change. But what about major and patch versions?

First, let’s pretend that no one uses your library. How can you detect breaking changes? The answer is… with tests.

If you modified the code, and you broke tests that described your public API, then the change is definitely incompatible. If your tests are green, then the change is definitely backwards compatible. Remember, no one uses your library, only your tests.

What is a bugfix? Bugs exist only because there was no test for that particular case. If there was no test for it, then you can safely fix behavior, because no one used that undocumented feature (remember, no one uses your library, only your tests).

Version over 9000

You might think that if you bump major version with every breaking change, then you’re going to end up with huge version numbers. You don’t have to release a new version after every change.

Wait, test it out, play with it, create prereleases. And if you think it’s time, you can release the next version with a tested/stable API.

I have no tests ☹

Well, shame on you! Luckily, you can substitute every occurrence of test with documentation.

If you had to modify existing documentation about the public API, then your change was major. If you only added new functionality (with new documentation), then it’s minor update, and if the documentation hasn't changed (or you only had to document a previously undefined behavior), then it’s a patch.

I have no documentation&tests ☹

Then you shouldn't worry, because no one uses your library anyway ☺.

Conclusion

Package managers like npm do care about version numbers, I don’t. If you want to publish something on npm, use semantic versioning. If you don’t use semver, at least you should warn the users about that, so they can avoid upgrades that break their code.