# Configuration (/docs/configuration)



snpm is configured from three sources, merged in this order (later wins):

1. Built-in defaults.
2. `.snpmrc` / `.npmrc` / `.pnpmrc` from the user's home directory, then each ancestor directory of the current working directory.
3. Environment variables.

Use `snpm config` to print the resolved configuration at any time.

Environment variables [#environment-variables]

Directories [#directories]

| Variable    | Description                                              | Default          |
| ----------- | -------------------------------------------------------- | ---------------- |
| `SNPM_HOME` | Sets `cache=$SNPM_HOME/cache` and `data=$SNPM_HOME/data` | Platform default |

Platform defaults:

* **macOS**: cache `~/Library/Caches/snpm`, data `~/Library/Application Support/io.snpm.snpm`
* **Linux**: cache `~/.cache/snpm`, data `~/.local/share/snpm`
* **Windows**: cache `%LOCALAPPDATA%\snpm\snpm\cache`, data `%LOCALAPPDATA%\snpm\snpm\data`

Derived directories (under the data dir):

* `packages/` — shared package store
* `metadata/` — registry metadata cache
* `virtual-store/` — shared virtual-store entries
* `global/` — global installs
* `bin/` — global bin shims

Registry and auth [#registry-and-auth]

| Variable                                                                  | Description                                                                          |
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `SNPM_CONFIG_REGISTRY` / `PNPM_CONFIG_REGISTRY` / `NPM_CONFIG_REGISTRY`   | Default registry URL. snpm prefers the snpm prefix, then pnpm, then npm.             |
| `SNPM_AUTH_TOKEN` / `NODE_AUTH_TOKEN` / `NPM_TOKEN`                       | Bearer token for the default registry. snpm picks the first non-empty in that order. |
| `SNPM_CONFIG__AUTH` / `PNPM_CONFIG__AUTH` / `NPM_CONFIG__AUTH`            | Base64-encoded `user:password` for Basic auth on the default registry.               |
| `SNPM_ALWAYS_AUTH` / `PNPM_CONFIG_ALWAYS_AUTH` / `NPM_CONFIG_ALWAYS_AUTH` | Truthy values force auth on every registry request.                                  |

When a token is set via `SNPM_AUTH_TOKEN`, `NODE_AUTH_TOKEN`, or `NPM_TOKEN`, the scheme is `Bearer`. When set via the `_auth` variants, it is `Basic`.

Install behavior [#install-behavior]

| Variable                                         | Default                           | Values                                                              |
| ------------------------------------------------ | --------------------------------- | ------------------------------------------------------------------- |
| `SNPM_HOIST`                                     | `single-version`                  | `none`, `single-version`, `all`                                     |
| `SNPM_LINK_BACKEND`                              | `auto`                            | `auto`, `hardlink`, `symlink`, `copy`                               |
| `SNPM_STRICT_PEERS`                              | `false`                           | truthy                                                              |
| `SNPM_FROZEN_LOCKFILE`                           | `false`                           | truthy                                                              |
| `SNPM_REGISTRY_CONCURRENCY`                      | `128`                             | integer > 0                                                         |
| `SNPM_DISABLE_GLOBAL_VIRTUAL_STORE_FOR_PACKAGES` | `next,nuxt,vite,vitepress,parcel` | Comma-separated names. Pass `[]` to disable the heuristic entirely. |

Truthy values: `1`, `true`, `yes`, `y`, `on`. snpm also accepts `snpm_config_*`, `pnpm_config_*`, and `npm_config_*` forms for `hoist`, `link_backend`, `strict_peer_dependencies`, `frozen_lockfile`, `registry_concurrency`, and `always_auth`.

Security [#security]

| Variable                          | Default | Description                                              |
| --------------------------------- | ------- | -------------------------------------------------------- |
| `SNPM_ALLOW_SCRIPTS`              | (empty) | Comma-separated packages allowed to run install scripts. |
| `SNPM_MIN_PACKAGE_AGE_DAYS`       | (unset) | Ignore versions published within N days.                 |
| `SNPM_MIN_PACKAGE_CACHE_AGE_DAYS` | `7`     | Re-fetch registry metadata older than N days.            |

Logging [#logging]

| Variable        | Default | Description                                                                                              |
| --------------- | ------- | -------------------------------------------------------------------------------------------------------- |
| `SNPM_VERBOSE`  | `false` | Enable verbose output (also `-v/--verbose`).                                                             |
| `SNPM_LOG_FILE` | (unset) | Custom log file path. When unset and verbose is enabled, snpm writes to `.snpm.log` in the project root. |

RC files [#rc-files]

snpm reads `.snpmrc`, `.npmrc`, and `.pnpmrc` in this order — home directory first, then ancestor directories of the current working directory. Later files override earlier ones.

```ini title=".snpmrc"
# Comments start with # or ;
registry=https://registry.npmjs.org/

# Scoped registries
@myorg:registry=https://npm.myorg.com/

# Auth tokens per host
//npm.myorg.com/:_authToken=${NPM_TOKEN}
//npm.myorg.com/:_auth=dXNlcjpwYXNz

# Default registry auth
_authToken=abc123

# Install behavior
snpm-hoist=single-version
link-backend=hardlink

# Force auth
always-auth=true

# Local virtual store packages
disable-global-virtual-store-for-packages=next,vite
```

`${VAR}` / `$VAR` expansion is supported in `.snpmrc` and `.npmrc` style files.

`snpm login` writes credentials to `~/.snpmrc` (falling back to a local `.snpmrc` if there is no home directory).

Hoisting [#hoisting]

```bash
export SNPM_HOIST=single-version   # default — only hoist when there is a single version
export SNPM_HOIST=none             # strict isolation, like pnpm's default
export SNPM_HOIST=all              # hoist aggressively, npm-style
```

Or per workspace:

```yaml title="snpm-workspace.yaml"
hoisting: single-version
```

Link backend [#link-backend]

```bash
export SNPM_LINK_BACKEND=auto       # default — hardlinks on Unix, copies on Windows
export SNPM_LINK_BACKEND=hardlink   # explicit hardlinks
export SNPM_LINK_BACKEND=symlink    # symlinks (good across filesystems)
export SNPM_LINK_BACKEND=copy       # explicit copy (slowest, most compatible)
```

Global virtual store compatibility [#global-virtual-store-compatibility]

snpm pools entries across projects in `<data_dir>/virtual-store/` so two projects with the same dep closure reuse the same bytes. Some packages must stay project-local — patched packages, packages allowed to run lifecycle scripts, directory-backed `file:` deps, and tools that walk up parent directories to find configuration.

The default project-local list is `next, nuxt, vite, vitepress, parcel`. Override it via env var or RC entry:

```bash
export SNPM_DISABLE_GLOBAL_VIRTUAL_STORE_FOR_PACKAGES=next,vite,vitepress
```

```ini title=".snpmrc"
disable-global-virtual-store-for-packages=next,vite
```

Set it to `[]` to disable the heuristic.

Script policy [#script-policy]

Dependency lifecycle scripts (`preinstall`, `install`, `postinstall`) are blocked by default.

```bash
export SNPM_ALLOW_SCRIPTS="esbuild,sharp,@swc/core"
```

Or via the workspace file:

```yaml title="snpm-workspace.yaml"
onlyBuiltDependencies:
  - esbuild
  - sharp
ignoredBuiltDependencies:
  - fsevents
```

Root project and workspace-member lifecycle scripts still run during install. After changing the allow-list, run `snpm rebuild` to apply the new policy to packages that already extracted.

Minimum package age [#minimum-package-age]

Ignore versions published within the last N days. Useful for production CI to dodge zero-day malicious publishes.

```bash
export SNPM_MIN_PACKAGE_AGE_DAYS=7
```

See [Security](/docs/security) for more.

Catalogs [#catalogs]

Workspace-wide dependency versions live in `snpm-catalog.yaml` and/or the `catalog`/`catalogs` blocks in `snpm-workspace.yaml`. See [Catalog](/docs/catalog).

Overrides [#overrides]

Force specific transitive dependency versions via `snpm-overrides.yaml` or `package.json`:

```yaml title="snpm-overrides.yaml"
overrides:
  lodash: ^4.17.21
  "@babel/core": ^7.23.0
```

```json title="package.json"
{
  "snpm": {
    "overrides": { "lodash": "^4.17.21" }
  },
  "pnpm": {
    "overrides": { "axios": "^1.6.0" }
  }
}
```

snpm reads both `snpm.overrides` and `pnpm.overrides` for compatibility.

Bundled dependencies [#bundled-dependencies]

`bundledDependencies` (or `bundleDependencies`) in `package.json` are honored. snpm respects the bundled versions for that package and prevents store pollution by keeping bundled copies project-local.

```json
{
  "bundledDependencies": ["fsevents", "node-gyp"]
}
```

Inspecting the resolved config [#inspecting-the-resolved-config]

Run `snpm config` to print resolved paths, registry/auth, install settings (hoisting, link backend, local virtual store packages, strict peers, frozen lockfile default, min package age, registry concurrency, always-auth), allow-scripts list, and logging configuration.

Common configurations [#common-configurations]

Development [#development]

```bash
export SNPM_REGISTRY_CONCURRENCY=128
unset SNPM_MIN_PACKAGE_AGE_DAYS
```

Production / CI [#production--ci]

```bash
export SNPM_MIN_PACKAGE_AGE_DAYS=7
export SNPM_FROZEN_LOCKFILE=1
export SNPM_ALLOW_SCRIPTS="esbuild,sharp"
snpm install --frozen-lockfile
```

Private registry [#private-registry]

```bash
export SNPM_CONFIG_REGISTRY=https://npm.mycompany.com
export NODE_AUTH_TOKEN=$MY_TOKEN
```

Or via login:

```bash
snpm login --registry https://npm.mycompany.com
snpm login --scope @myorg --registry https://npm.mycompany.com
```
