semver -l (--loose): accept 1.2.3beta, 01.2.3 and other almost-valid versions
- tool
- SemVer
- command
- semver
- flag
- -l, --loose
- default
- off (only strict SemVer 2.0.0 is accepted, apart from a leading v or =)
semver -l 1.2.3beta prints 1.2.3-beta: loose mode accepts versions that break small SemVer 2.0.0 rules and prints the normalised strict form. It allows a prerelease without the - separator (1.2.3beta), leading zeros in numbers (01.2.3, prerelease -01), and whitespace after the v. Without --loose, semver rejects those strings: it prints nothing and exits with 1. Loose mode does not invent missing parts; 1.2 stays invalid (that is what --coerce is for).
Strict versus loose parsing
node-semver's CLI is installed in a temporary folder (npx semver behaves the same):
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"
for v in "=v1.2.3" 1.2.3beta 01.2.3 "v 1.2.3" 1.2.3-01 "1.2.3 -beta" 1.2; do
strict=$(semver "$v"); s=$?
loose=$(semver -l "$v"); l=$?
printf '%-14s strict: %-12s (exit %s) loose: %-12s (exit %s)\n' "[$v]" "${strict:--}" "$s" "${loose:--}" "$l"
done
echo "--- loose ranges:"
semver -r '>=1.2.3beta' 1.2.5; echo "exit $?"
semver -l -r '>=1.2.3beta' 1.2.5; echo "exit $?"Output
[=v1.2.3] strict: 1.2.3 (exit 0) loose: 1.2.3 (exit 0) [1.2.3beta] strict: - (exit 1) loose: 1.2.3-beta (exit 0) [01.2.3] strict: - (exit 1) loose: 1.2.3 (exit 0) [v 1.2.3] strict: - (exit 1) loose: 1.2.3 (exit 0) [1.2.3-01] strict: - (exit 1) loose: 1.2.3-1 (exit 0) [1.2.3 -beta] strict: - (exit 1) loose: - (exit 1) [1.2] strict: - (exit 1) loose: - (exit 1) --- loose ranges: exit 1 1.2.5 exit 0
=v1.2.3 is accepted in both modes because node-semver always strips a leading = or v. The other malformed forms are accepted only with -l and printed in canonical form (1.2.3-beta, 1.2.3, 1.2.3-1). A space before the hyphen and a two-part version stay invalid. --loose also applies to ranges: a comparator with a loose version is ignored silently in strict mode, so the range matches nothing.
What loose mode relaxes
| Input | Strict | Loose | Rule relaxed |
|---|---|---|---|
| 1.2.3beta | invalid | 1.2.3-beta | Prerelease without - |
| 01.2.3 | invalid | 1.2.3 | Leading zero in a numeric part (SemVer item 2) |
| 1.2.3-01 | invalid | 1.2.3-1 | Leading zero in a numeric prerelease identifier (item 9) |
| v 1.2.3 | invalid | 1.2.3 | Whitespace after the v |
| =v1.2.3 | 1.2.3 | 1.2.3 | Already allowed in strict mode |
| 1.2 | invalid | invalid | Three parts are always required |
Loose, coerce or strict?
| Need | Use |
|---|---|
| Validate that input is real SemVer | Strict (no option); see the regex on validate a SemVer string |
| Accept old tags like 1.0.0beta2 and normalise them | --loose |
| Extract a version from free text (nginx/1.27.4) | --coerce |
| Accept prereleases in range matches | --include-prerelease |
Pitfalls
- Normalised output differs from input.
1.2.3-01becomes1.2.3-1; if you store the loose string and compare it later in strict mode, the comparison fails. Store the printed canonical form. - Library parity. In JavaScript pass
{ loose: true }tosemver.valid,satisfiesand the other functions; otherwise invalid input throws TypeError: Invalid Version. Python'ssemverpackage has no loose mode and raises ValueError: is not valid SemVer string. - Do not publish loose versions. npm refuses to publish a version that is not valid SemVer; fix the string instead. A strict pattern is on validate a SemVer string.
FAQ
Is v1.2.3 valid without --loose?
Yes, for node-semver: a leading v or = (and spaces after =) is stripped even in strict mode, so semver v1.2.3 prints 1.2.3. Strict SemVer 2.0.0 itself does not allow the v, which is why other libraries reject it.
Does --loose accept 1.2?
No. A version still needs three numeric parts. Use --coerce to turn 1.2 into 1.2.0.
Should I use --loose for package.json versions?
No. npm publishes and compares strict versions; loose parsing is meant for reading versions that other tools produced, such as old tags or vendor strings, and normalises them to strict SemVer.