NPM
npm package manager for Elixir — no Node.js required.
Resolve, fetch, cache, and link npm packages directly from Mix.
Installation
def deps do
[{:npm, "~> 0.6.1"}]
endUsage
# Initialize a new package.json
mix npm.init
# Install all deps from package.json
mix npm.install
# Add a package (latest)
mix npm.install lodash
# Add with version range
mix npm.install lodash@^4.0
# Scoped packages
mix npm.install @types/node@^20
# Add as dev dependency
mix npm.install eslint --save-dev
# Pin exact version (no ^ prefix)
mix npm.install lodash --save-exact
# Production install (skip devDependencies)
mix npm.install --production
# Remove a package
mix npm.remove lodash
# Update packages
mix npm.update # Update all
mix npm.update lodash # Update specific
# List installed packages
mix npm.list
# Show dependency tree
mix npm.tree
# Show outdated packages
mix npm.outdated
# Explain why a package is installed
mix npm.why accepts
# Show package info from the registry
mix npm.info express
# Search the registry
mix npm.search react
# Run a script from package.json
mix npm.run build
# Execute a binary from node_modules/.bin
mix npm.exec eslint .
# Fetch locked deps without re-resolving
mix npm.get
# CI mode — fail if lockfile is stale
mix npm.install --frozen
mix npm.ci
# Verify installation state
mix npm.check
# Clean node_modules
mix npm.clean
# Cache management
mix npm.cache status
mix npm.cache clean
# Show configuration
mix npm.configHow it works
-
Reads dependencies from
package.json(supportsdependencies,devDependencies,overrides) - Resolves the full dependency tree using PubGrub with npm semver
- Downloads tarballs from the npm registry with SHA-512/SHA-256/SHA-1 integrity verification
-
Caches packages globally in
~/.npm_ex/cache/— download once, reuse across projects -
Links into
node_modules/via symlinks (macOS/Linux) or copies (Windows) -
Creates
node_modules/.bin/with executable symlinks from packagebinfields -
Prunes stale packages from
node_modules/on re-install -
Locks versions in
npm.lockfor reproducible installs - Warns about unmet peer dependencies and deprecated packages
- Retries failed downloads with exponential backoff
Supply-chain safety
npm_ex does not run package lifecycle hooks automatically. Packages with preinstall, install, postinstall, or prepare scripts are still installed, but their hooks are ignored and reported as warnings. Tarball paths are also validated before extraction so package contents cannot escape the cache directory.
This blocks install-time credential stealers that rely on postinstall hooks reading files like .env and exfiltrating them during dependency installation.
Why npm.lock instead of package-lock.json?
npm_ex is not npm, so it keeps its own lockfile. package.json is the shared manifest; npm.lock is the reproducibility file for the npm_ex installer.
Configuration
Set environment variables to customize behavior:
NPM_REGISTRY— custom registry URL (default:https://registry.npmjs.org)NPM_TOKEN— authentication token for private registriesNPM_EX_CACHE_DIR— custom cache directory (default:~/.npm_ex/)
License
MIT © 2026 Danila Poyarkov