node-semver: [BUG] Version with v-prefix is incorrectly marked as valid

According to SemVer 2.0.0, a version like v1.2.3 is not valid (https://semver.org/#is-v123-a-semantic-version).

The library incorrectly marks a version like this as valid:

const semverValid = require('semver/functions/valid')

semverValid('v1.2.3')
// true

semverValid('v1.2.3', {loose: false})
// true

I understand that the v-prefix is often used to indicate that some string represents a version. However, when I explicitly want to check if a string is valid according to the SemVer spec, I expect the method to return false in this case, especially when I set the loose option to false.

A fix (or an option to be extra strict for backwards compatibility) would be appreciated!

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 2
  • Comments: 24 (5 by maintainers)

Commits related to this issue

Most upvoted comments

The npm ecosystem doesn’t follow semver 2.0 - it follows 1.0, i believe - because version changes under v1 aren’t always breaking.

@ljharb This is only mostly correct.

The npm ecosystem started with SemVer 1.0, which was a much less clear and precisely worded spec. SemVer 2.0 brought a lot more rigor, but the npm ecosystem already had a fairly large corpus of version numbers that were only compliant with (a particular interpretation of) SemVer 1.0. So, it has “strict mode” (used for publishing, npm version, and so on) and a “loose mode” (used for interpreting the versions of dependencies, since they might be from the prior age).

The presence of a v has always been allowed, which yes, is somewhat “nonstandard” according to the spec. But semver.valid('v1.2.3') will return the “canonical” form '1.2.3'. Arguably a more strict API there would’ve been more correct, but in many instances less useful, since this is also used to pull out versions from git tags created by npm, which by default do have the v prefix.

Historical accidents all the way down, but the cost of changing to not allow the v in semver.valid() is almost certainly higher than any value it would provide. If you really want to detect whether a version is 100% strict and compliant, just replace this:

if (semver.valid(version)) {

with this:

if (version === semver.valid(version)) {

I think it’s worth exploring a way to make valid choose between v1 and v2. Docs would probably end up being part of that PR right?

make sense for the explaining of how npm ecosystem works and that difficult to change. there still 2 things who can be improved:

  • the readme say this package follow the spec v2 where it should say v1 of semver then
  • the valid method could have option to be “ultra scrict” or v2.

For both improvement i’m willing to make a PR but i would like to know if you are open to this changes

I do agree that a “strict” mode that actually follows the spec would be nice. As seen in https://github.com/npm/cli/issues/6370, the currently sloppy parsing already causes issues for npm itself.