# Introduction (/docs)



**snpm** is a Rust-native package manager for Node.js projects, shaped around pnpm-style workflows: a shared package store, a `node_modules/.snpm` virtual store, workspace-aware installs, and a lockfile-first install path.

<Callout type="info">
  The core install, workspace, registry, cache, script-policy, and package workflow surfaces are in place. snpm reads pnpm/Bun/Yarn/npm lockfiles when its own is missing, then continues with `snpm-lock.yaml` as the source of truth.
</Callout>

What you get [#what-you-get]

* **Drop-in workflow** — `snpm install`, `snpm add`, `snpm run`, `snpm exec`, `snpm dlx`, plus a script-name fallback (`snpm build` runs `build`).
* **Shared package store** with hardlinks/symlinks/copies, and a project-local `node_modules/.snpm` virtual store keyed by version + dependency closure.
* **Workspaces** discovered from `snpm-workspace.yaml`, `pnpm-workspace.yaml`, or `package.json` `workspaces`, with rich `--filter`/`--filter-prod` selectors (name, glob, path, `pkg...`, `...pkg`, `[git-ref]`, `!exclude`).
* **Catalogs and overrides** through `snpm-catalog.yaml`, `snpm-overrides.yaml`, and `package.json` `snpm` / `pnpm` blocks.
* **Lockfile imports** — `pnpm-lock.yaml`, `bun.lock`, `yarn.lock`, `npm-shrinkwrap.json`, and `package-lock.json` seed the first install if `snpm-lock.yaml` is missing.
* **Registry auth** with Bearer/Basic schemes, scoped registries, and `.snpmrc` / `.npmrc` / `.pnpmrc` parsing.
* **Security defaults** — dependency lifecycle scripts blocked unless explicitly allowed, `SNPM_MIN_PACKAGE_AGE_DAYS` to skip recent publishes, tarball auth scoped to the announcing registry origin.
* **First-party publishing** — `pack`, `publish`, `pack --dry-run`, distribution tags, OTP support.
* **Inspection** — `audit` (table/json/SARIF, `--fix`), `why`, `licenses`, `store status`, `outdated`, `list`.
* **Local development** — `link`, `unlink`, `patch edit/commit/remove/list`, `rebuild`.
* **Node version manager** — `snpm node install`, `node use`, `.node-version` / `.nvmrc` / `engines.node` discovery, shell hooks.

Quick start [#quick-start]

```bash
# Install snpm
npm install -g snpm

# Work in a project
snpm install
snpm add react
snpm add -D typescript
snpm remove left-pad
snpm run build
snpm exec eslint .
snpm dlx cowsay "hello"
```

In a workspace:

```bash
snpm install
snpm install -w @acme/api
snpm run build -r
snpm run test --filter "@acme/*"
snpm run test --filter api...
snpm add -r -D vitest
```

In CI:

```bash
snpm install --frozen-lockfile
snpm install --production --frozen-lockfile
SNPM_MIN_PACKAGE_AGE_DAYS=7 snpm install --frozen-lockfile
```

How it works [#how-it-works]

**Shared store** — Packages are downloaded once into `<data_dir>/packages/<name>/<version>/` and linked into each project's `node_modules/.snpm` virtual store. The default linker is `auto` (hardlinks on Unix, copies on Windows), with `hardlink`, `symlink`, and `copy` backends available.

**Virtual store** — Each project gets a `node_modules/.snpm` directory keyed by package version and resolved dependency closure. Shared entries are pooled across projects when safe; patched, script-enabled, directory-backed `file:`, and resolver-walk-up-sensitive packages stay project-local automatically.

**Lockfile** — `snpm-lock.yaml` (schema version `1`) is the source of truth. Installs validate cached state against a lockfile-derived hash stored in `node_modules/.snpm-integrity`; if it matches, install completes in milliseconds.

**Script policy** — Dependency lifecycle scripts are blocked by default. Root project scripts (`preinstall`, `install`, `postinstall`, `prepare`) still run during install. Allow specific dependency packages via `SNPM_ALLOW_SCRIPTS=...` or workspace `onlyBuiltDependencies`.

**Registry compatibility** — `npm`, `jsr`, `file:`, `git:`, `workspace:`, and `catalog:` protocols are supported. Auth is read from `.snpmrc` / `.npmrc` / `.pnpmrc`, environment variables, and the credentials saved by `snpm login`.
