npm-compatible semantic versioning for Elixir — parse, match, and compare versions using npm range syntax with hex_solver integration
Find a file
2026-06-11 12:21:49 +03:00
.github/workflows Add CHANGELOG, GitHub Actions CI, update README 2026-03-11 11:13:27 +03:00
lib Add CI tooling: credo, ex_dna, ex_slop, dialyzer 2026-03-11 11:12:10 +03:00
test Add CI tooling: credo, ex_dna, ex_slop, dialyzer 2026-03-11 11:12:10 +03:00
.credo.exs Add CI tooling: credo, ex_dna, ex_slop, dialyzer 2026-03-11 11:12:10 +03:00
.dialyzer_ignore.exs Add CI tooling: credo, ex_dna, ex_slop, dialyzer 2026-03-11 11:12:10 +03:00
.formatter.exs Initial implementation 2026-03-11 11:05:34 +03:00
.gitignore Initial implementation 2026-03-11 11:05:34 +03:00
CHANGELOG.md Add CHANGELOG, GitHub Actions CI, update README 2026-03-11 11:13:27 +03:00
LICENSE Initial implementation 2026-03-11 11:05:34 +03:00
mix.exs Update URLs to elixir-volt org 2026-03-12 19:15:55 +03:00
mix.lock Add CI tooling: credo, ex_dna, ex_slop, dialyzer 2026-03-11 11:12:10 +03:00
README.md README: ecosystem footer linking org and Building Blocks standard 2026-06-11 12:21:49 +03:00

NPMSemver

Hex.pm CI

npm-compatible semantic versioning for Elixir.

Parse and match version ranges using npm's semver syntax: ^1.2.3, ~1.2.3, >=1.0.0 <2.0.0, 1.x, 1.0.0 - 2.0.0, || unions.

Installation

def deps do
  [{:npm_semver, "~> 0.1.0"}]
end

Usage

NPMSemver.matches?("1.2.3", "^1.0.0")
# => true

NPMSemver.matches?("2.0.0", "^1.0.0")
# => false

NPMSemver.matches?("1.5.0", ">=1.2.3 <2.0.0")
# => true

NPMSemver.matches?("2.1.3", "2.x.x")
# => true

Find best match

NPMSemver.max_satisfying(["1.0.0", "1.5.0", "2.0.0"], "^1.0.0")
# => "1.5.0"

hex_solver integration

Convert npm ranges to constraints for hex_solver (PubGrub dependency resolver):

{:ok, constraint} = NPMSemver.to_hex_constraint("^1.2.3")

Or get the Elixir requirement string directly:

NPMSemver.to_elixir_requirement("^1.2.3")
# => {:ok, ">= 1.2.3 and < 2.0.0-0"}

Supported syntax

Syntax Example Expands to
Caret ^1.2.3 >=1.2.3 <2.0.0
Tilde ~1.2.3 >=1.2.3 <1.3.0
X-range 1.2.x, 1.*, * >=1.2.0 <1.3.0
Comparator >=1.0.0 <2.0.0 as written
Hyphen 1.0.0 - 2.0.0 >=1.0.0 <=2.0.0
Union ^1.0 || ^2.0 either range
Intersection >=1.2.1 <=1.2.8 space-separated AND

Options

  • loose: true — accept v-prefixed versions and pre-release tags without - separator
  • include_prerelease: true — x-ranges and * match pre-release versions

Testing

216 test cases ported from node-semver fixtures.

Part of Elixir Volt

npm_semver brings npm-compatible semantic version ranges to Elixir.

It is part of a frontend stack that runs inside the BEAM — builds, JS runtimes, icons, and Vue-to-LiveView compilation as supervised parts of the application instead of external toolchain processes. See the Elixir Volt organization for the rest, and Building Blocks for the Future Web for the thesis, architecture, and roadmap that tie them together.

License

MIT