Skip to content

/flags/semver/semver-p-include-prerelease

semver -p (--include-prerelease): let ^1.2.0 match 1.3.0-beta.1

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
SemVer
command
semver
flag
-p, --include-prerelease
default
off (a range matches a prerelease only when a comparator in the range has a prerelease on the same major.minor.patch)

semver -p -r '^1.2.0' 1.3.0-beta.1 makes the range match prerelease versions as well. By default node-semver excludes prereleases from ranges: ^1.2.0 matches 1.3.0 but not 1.3.0-beta.1 or 1.2.5-rc.1, even though they fall between the bounds numerically. The rule protects users from installing unstable versions by accident; -p (--include-prerelease, the includePrerelease option in the library) turns it off.

Matching with and without -p

node-semver's CLI is installed in a temporary folder (npx semver behaves the same). -r prints the versions that satisfy the range, and exits with 1 if none does:

bash
npm init -y >/dev/null && npm install --silent --no-audit --no-fund semver@7.8.5 >/dev/null 2>&1
export PATH="$PWD/node_modules/.bin:$PATH"
echo "--- ^1.2.0 without -p:"
semver -r '^1.2.0' 1.2.5-rc.1 1.3.0-beta.1 1.3.0
echo "--- ^1.2.0 with -p:"
semver -p -r '^1.2.0' 1.2.5-rc.1 1.3.0-beta.1 1.3.0
echo "--- a range that names a prerelease:"
semver -r '^1.2.5-rc.0' 1.2.5-rc.1 1.3.0-beta.1
echo "--- only prereleases, no -p:"
semver -r '^1.2.0' 1.3.0-beta.1; echo "exit $?"
echo "--- sorting is unchanged:"
semver 1.3.0 1.3.0-beta.1 1.3.0-rc.1

Output

--- ^1.2.0 without -p:
1.3.0
--- ^1.2.0 with -p:
1.2.5-rc.1
1.3.0-beta.1
1.3.0
--- a range that names a prerelease:
1.2.5-rc.1
--- only prereleases, no -p:
exit 1
--- sorting is unchanged:
1.3.0-beta.1
1.3.0-rc.1
1.3.0

Without -p only 1.3.0 matches. With it, both prereleases match too. A range that itself contains a prerelease (^1.2.5-rc.0) admits prereleases of that version tuple only: 1.2.5-rc.1 matches, 1.3.0-beta.1 does not. When nothing matches, semver prints nothing and exits with 1.

The default rule in detail

RangeVersionDefaultWith -p
^1.2.01.3.0matchmatch
^1.2.01.3.0-beta.1no matchmatch
>=1.2.0-rc.01.2.0-rc.5match (same tuple 1.2.0)match
>=1.2.0-rc.01.3.0-beta.1no match (different tuple)match
*2.0.0-alpha.1no matchmatch
2.0.0-alpha.12.0.0-alpha.1match (exact)match

The "same tuple" exception exists so that a project that already opted into 1.2.0-rc.0 receives newer release candidates of 1.2.0, but not the prereleases of every later version.

Where the option exists

  • CLI: semver -p or --include-prerelease.
  • Library: semver.satisfies(v, range, { includePrerelease: true }), and the same option for maxSatisfying, minSatisfying and Range.
  • npm installs follow the default rule: a prerelease is installed only when you ask for it by version, by a range that names it, or by a dist-tag such as beta.

Pitfalls

  • Wildcards. * and x ranges also exclude prereleases by default, so semver -r '*' 2.0.0-alpha.1 prints nothing.
  • Invalid ranges. A malformed range makes the library throw TypeError: Invalid comparator; the CLI prints nothing and exits with 1.
  • Publishing betas. Publish prereleases with npm publish --tag beta so latest keeps pointing at the stable release; bump them with semver -i prerelease --preid.

The full range grammar is on SemVer range syntax and the concept on pre-release versions.

FAQ

Why does npm not install my beta although it is newer?

A range such as ^1.2.0 only matches prereleases when the range itself names a prerelease of the same major.minor.patch. Install the beta explicitly (npm install pkg@beta or pkg@1.3.0-beta.1) or use a range like ^1.3.0-beta.0.

Does -p change how versions are sorted?

No. Prereleases always sort before their release (1.3.0-beta.1 < 1.3.0). -p only changes which versions a range is allowed to match.

How do I get the newest version including prereleases in code?

Pass the option to the library: semver.maxSatisfying(versions, '^1.2.0', { includePrerelease: true }). Without it, maxSatisfying ignores prereleases just like the CLI without -p.

Sources