Current section
Files
Jump to
Current section
Files
duskmoon_npm
README.md
README.md
# NPM[](https://hex.pm/packages/npm)[](https://github.com/elixir-volt/npm_ex/actions/workflows/ci.yml)npm package management for Elixir — resolve, fetch, cache, and link npm packages from Mix without requiring Node.js for installation.```shmix npm.install lodashmix npm.exec eslint .````npm_ex` reads `package.json`, resolves npm semver with PubGrub, writes `npm.lock`, and links packages into `node_modules/`.## Why npm_exElixir projects increasingly need JavaScript packages for assets, formatters, linters, browser libraries, and runtime integrations. npm_ex keeps that workflow inside Mix:- no `npm install` step required for dependency resolution or linking- reproducible installs through `npm.lock`- global package cache in `~/.npm_ex/cache/`- npm registry auth, mirrors, scoped registries, peer/deprecation warnings- CI-friendly Mix tasks for install, verify, audit, outdated, tree, and exec## Installation```elixirdef deps do [{:duskmoon_npm, "~> 9.5.1"}]end``````shmix npm.initmix npm.install lodash```## Common workflows```sh# Install and maintain dependenciesmix npm.installmix npm.install lodash@^4.0mix npm.install eslint --save-devmix npm.updatemix npm.remove lodash# CI / reproducibilitymix npm.install --frozenmix npm.cimix npm.verify# Inspect dependency statemix npm.listmix npm.treemix npm.why acceptsmix npm.outdated# Run scripts and binariesmix npm.run buildmix npm.exec eslint .# Registry, cache, and configmix npm.info expressmix npm.search reactmix npm.cache statusmix npm.config```## How installs work1. Read `package.json` dependencies, dev dependencies, optional dependencies, and overrides.2. Resolve the full dependency tree using [duskmoon_hex_solver](https://hex.pm/packages/duskmoon_hex_solver) and the bundled npm semver parser.3. Fetch registry packuments and tarballs with integrity verification.4. Store package contents in the global cache.5. Link packages into `node_modules/` and write `npm.lock`.`npm_ex` uses its own `npm.lock` because it is not npm. `package.json` remains the shared manifest; `npm.lock` records npm_ex's resolved dependency graph and security policy.## Supply-chain safetynpm_ex is intentionally conservative around install-time code execution:- package lifecycle hooks are **not executed automatically**- packages declaring `preinstall`, `install`, `postinstall`, or `prepare` are installed but reported as warnings- tarball paths are validated before extraction to prevent cache escapes- transitive git, URL, GitHub shorthand, and `file:` dependencies are blocked by default- direct exotic dependencies require an explicit `exotic_deps` allowlist entry- registry origins and redirects are policy checked- newly created packages and freshly published versions can warn during installThis blocks common install-time credential stealers that rely on postinstall hooks reading files like `.env` and exfiltrating secrets during dependency installation.## Auditing malicious packages`mix npm.audit` supports npm vulnerability checks and OSV/OpenSSF malicious-package intelligence:```sh# npm registry vulnerability auditmix npm.audit# Strict online OSV malicious-package gatemix npm.audit --osv# Refresh the shared local malicious-package cache for the current lockfilemix npm.audit --osv --write-cache --policy warn# Deterministic offline gate using the shared cache or configured DBmix npm.audit --compromised````--write-cache` merges matching OSV advisories into `~/.npm_ex/security/compromised_packages.json` by default. `mix npm.audit --osv` fails closed when OSV cannot be queried; `mix npm.audit --compromised` is offline and deterministic.OpenSSF/OSV is the default-compatible open data source. Socket, Snyk, and Phylum provide valuable proprietary intelligence or install-time firewall workflows; they fit best as external scanners/proxies or future optional integrations rather than default npm_ex install dependencies.## ConfigurationMost projects only need the defaults. Use `mix npm.config` to inspect effective settings.Common environment variables:- `NPM_REGISTRY`, `NPM_TOKEN`, `NPM_MIRROR`- `NPM_EX_CACHE_DIR`, `NPM_INSTALL_DIR`- `NPM_EX_BLOCK_EXOTIC_SUBDEPS`, `NPM_EX_EXOTIC_DEPS`- `NPM_EX_ALLOWED_REGISTRIES`, `NPM_EX_ALLOW_REGISTRY_REDIRECTS`- `NPM_EX_PACKAGE_AGE_WARNING_DAYS`, `NPM_EX_VERSION_AGE_WARNING_DAYS`- `NPM_EX_COMPROMISED_DB_PATH`, `NPM_EX_COMPROMISED_POLICY`Elixir application config is also supported:```elixirconfig :duskmoon_npm, registry: "https://registry.npmjs.org", token: System.get_env("NPM_TOKEN"), cache_dir: Path.expand("~/.npm_ex"), block_exotic_subdeps: true, exotic_deps: [], allowed_registries: ["https://registry.npmjs.org"], allow_registry_redirects: false, package_age_warning_days: 7, version_age_warning_days: 3, compromised_db_path: Path.expand("~/.npm_ex/security/compromised_packages.json"), compromised_policy: :error```## API organizationThe main public API is `NPM`. Supporting modules are grouped by domain: `NPM.Package.*`, `NPM.Dependency.*`, `NPM.Lockfile.*`, `NPM.Security.*`, `NPM.Registry.*`, `NPM.Config.*`, `NPM.Install.*`, `NPM.Node.*`, `NPM.NodeModules.*`, and `NPM.Diagnostics.*`.See `CHANGELOG.md` for the 0.7 migration map from older pre-namespace module names.## DocumentationFull guides and API documentation are available on [HexDocs](https://hexdocs.pm/npm):- Getting Started- Dependency Workflows- CI and Reproducibility- Supply-Chain Safety- Malicious Package Audits- Configuration- CLI and configuration cheatsheets## LicenseMIT © 2026 Danila Poyarkov