0.7.4
Fixed
- Preserve file permissions from tarballs during extraction, fixing EACCES for native executables like
tsgo - Run package scripts directly with
nodeso package#importsresolve correctly - Detect native binaries and execute them directly instead of wrapping in a Node.js loader
- Propagate non-zero exit codes from
mix npm.runandmix npm.execto the shell - Accept lockfiles without a policy section in
--frozeninstall - Include
optionalDependenciesin lockfile consistency check for--frozeninstall
0.7.3
- Skip
browserfield during resolution when its target extension is not in the resolvable set (fixes daisyUI resolving to.csswhen bundling JS) - Resolve package subpaths directly when no
exportsmap is present, instead of falling back to root entry
0.7.2
Fixed
- Extract tarballs with a non-
package/root directory, such as DefinitelyTyped@types/*packages, into the package root.
0.7.1
Fixed
- Skip package versions with blocked transitive exotic dependencies during dependency solving instead of aborting resolution before a safe version can be selected.
0.7.0
Breaking changes
- Reorganize supporting modules under domain namespaces. Compatibility wrapper modules were not retained because
npm_exis still pre-1.0. - Direct exotic dependencies such as
git:, GitHub shorthands, URLs, andfile:specs now require an explicitexotic_depsallowlist entry. - Transitive exotic dependencies from published package metadata are blocked by default.
- Lockfiles written without the current dependency security policy are treated as stale.
Security hardening
- Block transitive git, file, and URL dependency specs from published package metadata by default
- Add
config :npmsupport for registry, token, mirror, cache dir, install dir, registry policy, package age warnings, and exotic dependency policy - Move dependency analysis modules under
NPM.Dependency.*and node_modules path helpers underNPM.NodeModules.Path - Move supply-chain security helpers under
NPM.Security.* - Move lockfile helper modules under
NPM.Lockfile.* - Move package metadata helpers under
NPM.Package.* - Route JSON decoding through
NPM.JSONacross library modules - Move health, doctor, environment, and engine checks under
NPM.Diagnostics.* - Move registry and
.npmrchelpers underNPM.Registry.*andNPM.Config.* - Move install/runtime helpers under
NPM.Install.*andNPM.Node.* - Enforce registry origin allowlists for packuments and tarballs
- Record dependency security policy in
npm.lockand invalidate locks generated with weaker policy - Block direct exotic dependencies unless their exact specs are listed in
exotic_deps - Warn when registry metadata shows newly created packages or freshly published versions
- Add
NPM.Security.Compromisedandmix npm.audit --osv/--compromisedfor OSV-backed malicious package checks - Merge OSV advisory writes into the shared compromised-package cache and fail online audit on OSV query errors
Migration map
0.6.1
- Harden tarball extraction against path traversal and absolute-path entries
- Preserve install-script metadata in
npm.lock - Warn when dependencies declare ignored lifecycle scripts
- Document that
npm_exdoes not run package lifecycle hooks automatically, mitigating install-time credential stealers
0.6.0
- Move resolution modules under
NPM.Resolution:PackageResolver,Exports, andConditional - Support nested conditional package exports, array targets, and wildcard export patterns in
NPM.Resolution.Exports - Add package
importsresolution for internal specifiers such as#compiler/builders - Add
NPM.Resolution.PackageResolver.nearest_package/1andNPM.Resolution.PackageResolver.package_root/2 - Harden package resolution for modern packages such as Svelte and
@jridgewell/* - Fix optional tarball linker test isolation
0.5.3
- Add
NPM.PackageResolver.relative_import_path/3— compute relative import paths between files within a project root, with guaranteed.//../prefix
0.5.2
- Add
NPM.PackageResolver— Node.js module resolution algorithm (specifier parsing,node_modulestraversal,package.jsonentry points, extension probing) - Fix ETS race condition in
NPM.Resolvercache initialization - Fix
NPM.Cache.ensure/5spec and docs to include{:ok, :missing_optional}return - Fix dead code in
NPM.PeerDepsversion matching (redundant boolean case) - Fix
NPM.FileSize.by_extension/1dead||branch (Path.extnamenever returns nil) - Fix
NPM.DepSort.install_order/1dead{:error, :cycle}branch - Fix crash in
NPM.Install.Linkernested version resolution on unparseable versions - Replace blanket
rescue _with specific exception types across the codebase - Flatten nesting in
expand_all_optional_deps,solver_dependencies,select_group - Bump ex_dna
~> 1.1→~> 1.3
0.5.1
- Platform-agnostic lockfile:
npm.locknow includes all optional platform bindings, not just the current platform - Only install matching platform bindings into
node_modulesat link time - Lockfiles are now portable across OS/arch — same as npm's
package-lock.jsonbehavior
0.5.0
- Add
NPM.install/2for script context — works likeMix.install/2, installs to a content-addressed cache directory without requiring a Mix project - Add
NPM.installed?/0,NPM.install_dir!/0,NPM.node_modules_dir!/0helpers mix npm.installnow accepts multiple packages:mix npm.install lodash react vue- Fix infinite loop when a package lists itself as a dependency (e.g.
sqlite-napi)
0.4.6
- Add packument disk cache (
~/.npm_ex/packuments/) with 1h TTL — avoids refetching registry metadata on repeat installs - Skip resolution entirely when lockfile matches
package.jsonandnode_modulesis intact
0.4.5
- Switch default linker strategy from symlink to copy, fixing ESM module resolution for cached packages
- Fix
NodeRunnerentrypoint resolution to follow bin symlinks correctly - Cache platform binding selection results, reducing resolve time from ~35s to ~1.5s for packages like
oxfmt - Generalize platform binding family detection for both old-style (
@oxfmt/darwin-arm64) and new-style (@oxfmt/binding-darwin-arm64) naming - Avoid grouping non-platform optional dependencies (e.g.
@babel/core) as platform variants
0.4.4
- Fix npm registry packument decoding for optional platform dependency inspection
- Select the correct platform-specific optional binding for packages like
oxfmtandoxlint - Keep
mix npm.execrunning binaries through Node instead of shell string spawning - Preserve
optional_dependenciesinnpm.lock - Skip linking crashes when optional packages are unavailable
0.4.3
- Fix
mix npm.execto resolve binaries viaNPM.Node.Exec.which/2and run them through Node instead of shell string spawning - Preserve
optional_dependenciesinnpm.lock - Skip linking missing optional packages instead of crashing during install
- Add focused test coverage for exec environment, cached Node runner execution, optional runtime linking, and resolver optional dependency handling
0.4.2
- Speculative parallel prefetch of transitive dependencies before solving — fetches the full dep tree breadth-first with 16 concurrent requests
- Deduplicate
format_size/format_bytesacross 8 modules intoNPM.Format.bytes/1
0.4.1
- Fix mix tasks crashing with
unknown registry: Req.Finchwhen host app hasn't started the HTTP stack
0.4.0
New Mix Tasks (21 new, 43 total)
mix npm.init— create a newpackage.jsonmix npm.update— update all or specific packagesmix npm.outdated— show packages with newer versions availablemix npm.tree— display full dependency treemix npm.why/mix npm.explain— explain why a package is installedmix npm.info/mix npm.view— show package details from the registrymix npm.search— search the npm registrymix npm.run— run scripts frompackage.jsonmix npm.exec— execute binaries fromnode_modules/.bin/mix npm.ci— frozen lockfile install (CI shortcut)mix npm.check/mix npm.verify— verify installation statemix npm.clean— removenode_modules/mix npm.cache— manage global cachemix npm.config/mix npm.set— show and modify configurationmix npm.version— show npm_ex versionmix npm.link— link local packages for developmentmix npm.diff— show lockfile changes since last commitmix npm.pack— create a tarball of the current packagemix npm.audit— check for security vulnerabilitiesmix npm.dedupe— re-resolve to minimize duplicatesmix npm.prune— remove extraneous packagesmix npm.fund— show package funding infomix npm.rebuild— clean and reinstall from lockfilemix npm.uninstall— alias fornpm.removemix npm.deps— list installed packages (mix deps-style output)mix npm.deprecations— show deprecated packagesmix npm.doctor— diagnose common setup problemsmix npm.licenses— list dependency licensesmix npm.ls— alias formix npm.listmix npm.publish— publish package to registrymix npm.shrinkwrap— generate npm-shrinkwrap.jsonmix npm.size— estimate installed package sizesmix npm.stats— show dependency statisticsmix npm.token— manage registry auth tokensmix npm.completion— shell completion helpers
Install UX
mix deps-style output after install — packages listed as* name version (npm registry)- Progress reporting for resolution, fetching, and linking steps
- Structured error messages with actionable suggestions
- Lockfile diff output showing added/removed/updated packages on install
- Project setup checklist (
NPM.ProjectInit)
Dependency Analysis (30+ modules)
NPM.DepGraph— adjacency list, fan-in/out, cycle detection, orphansNPM.GraphOps— transitive closure, shortest path, impact scoringNPM.DepSort— topological sorting, parallel install levelsNPM.DepRange— classify ranges (exact, caret, tilde, star, file, git, url)NPM.DepConflict— detect version conflicts between dependency groupsNPM.DepFreshness— classify package freshness (current, outdated, ancient)NPM.DepStats— aggregate statistics (scope distribution, version breakdown)NPM.DepPath— resolve bin and module paths within node_modulesNPM.DepCheck— verify installed tree matches lockfileNPM.PhantomDep— detect undeclared (phantom) dependenciesNPM.HoistingConflict— detect version conflicts from hoistingNPM.PeerDep/NPM.PeerDepsCheck— peer dependency validationNPM.PackageUpdate— compute available major/minor/patch updatesNPM.OutdatedReport— npm outdated-style table formattingNPM.SnapshotDiff— lockfile snapshot comparisonNPM.Package.Manifest.Diff— diff two package.json filesNPM.IntegrityCheck— verify installed packages match lockfileNPM.LockfileCheck/NPM.LockfileStats— lockfile validation and metrics
Package Metadata (20+ modules)
NPM.Validate— package.json schema validationNPM.Engines/NPM.NodeVersion— engine constraints and .nvmrc/.tool-versions parsingNPM.Compat— Node.js version compatibility checkingNPM.Package.Funding— funding field parsingNPM.TypeField— module type detection (ESM/CJS)NPM.SideEffects— tree-shaking side-effects fieldNPM.Conditional— conditional exports/imports resolutionNPM.Exports/NPM.TypesResolution— package exports and types resolutionNPM.Package.PublishConfig— publish configurationNPM.Corepack— packageManager field parsingNPM.Package.Quality— metadata quality scoringNPM.Package.Files— files field and .npmignore analysisNPM.BundleAnalysis— bundle-friendliness scoringNPM.ImportMap— browser import map generationNPM.TypesCompanion— suggest @types/* companion packagesNPM.Install.ScriptRunner— script analysis and pattern detectionNPM.ReleaseNotes— changelog version extraction
Security & Supply Chain
NPM.CVE— CVE detection and scoringNPM.SBOM— software bill of materials generationNPM.SupplyChain— supply chain risk assessmentNPM.Provenance— package provenance verificationNPM.DeprecationAnalysis— deprecation severity analysis
Configuration
NPM.Config.Npmrc— .npmrc file parsingNPM.Config.Npmrc.Merge— multi-layer .npmrc resolution (project → user → global)NPM.Registry.URL— registry URL resolution with scope supportNPM.InstallStrategy— hoisted/nested/isolated install strategiesNPM.Workspaces— workspace configuration and glob matchingNPM.Migration— npm version migration guidance
Infrastructure
NPM.Compiler— Mix compiler for automatic npm installsNPM.CacheStats— cache hit/miss metrics and disk usageNPM.ProgressReporter— structured progress outputNPM.ErrorMessage— error formatting with suggestionsNPM.DepsOutput—mix deps-style package listingNPM.Diagnostics— project health diagnosticsNPM.Gitignore— .gitignore management for npm projects
Other
devDependenciessupport (--save-dev,--production)optionalDependenciessupport (--save-optional)--save-exactflag for pinning exact versionsnode_modules/.bin/executable linkingoverridessupport inpackage.json- Custom registry URL via
NPM_REGISTRYenv var - Auth token support via
NPM_TOKENenv var - SHA-256 integrity verification (in addition to SHA-512 and SHA-1)
- Retry with exponential backoff for failed HTTP requests
file:dependency references- 2,697 tests (up from 64)
0.3.1
- Rename repository to npm_ex
0.3.0
mix npm.remove— remove a package frompackage.jsonmix npm.list— show installed packages with versionsmix npm.install --frozen— fail if lockfile is stale (CI mode)- Fix scoped package parsing (
@scope/pkg@^1.0was splitting incorrectly) - Timing output for resolve and install steps
- Rename
install/2toadd/2in the public API - Expand test suite to 64 tests
0.2.0
- Global package cache at
~/.npm_ex/cache/— download once, reuse across projects node_modules/linking via symlinks (unix) or copies (Windows)- Hoisted flat layout
- Switch from
:httpcto Req for HTTP - Add
mix npm.gettask - Add credo, ex_slop, ex_dna, dialyzer
- Add unit and integration tests
- Add GitHub Actions CI
0.1.0
Initial release.
mix npm.install— resolve and install all deps frompackage.jsonmix npm.install <pkg>— add a package and install- PubGrub dependency resolution via
hex_solver - npm registry client with abbreviated packuments
- SHA-512 integrity verification
npm.locklockfile for reproducible installs