Configuration
scpm reads pnpm-compatible configuration from project .npmrc, user .npmrc,
user scpm config, scpm-workspace.yaml, environment variables, and supported
CLI flags. Existing pnpm-workspace.yaml files are migration inputs.
Defaults worth knowing
| Area | Default | Why it matters |
|---|---|---|
| Linker | nodeLinker=isolated | Keeps transitive dependencies scoped to the packages that declared them. |
| Package imports | packageImportMethod=auto | Hardlinks files from the store, falling back to copy on cross-filesystem boundaries. Opt into reflink with clone or clone-or-copy. |
| New releases | minimumReleaseAge=1440 | Avoids installing versions published in the last 24 hours by default. |
| Exotic transitive deps | blockExoticSubdeps=true | Blocks transitive git and tarball dependencies unless you opt out. |
| Dependency scripts | approval required | Build scripts in dependencies stay skipped until approved. |
| Jailed builds | jailBuilds=false | Opt in to running approved dependency scripts with a restricted env, temporary HOME, and native macOS jail. Planned to default to true in the next major version. |
| Auto-install before scripts | enabled | scpm run, scpm test, and scpm exec repair stale installs first. |
User scpm config
scpm config set writes user-scope settings to ~/.config/scpm/config.toml by
default. If XDG_CONFIG_HOME is set, the path is $XDG_CONFIG_HOME/scpm/config.toml.
minimumReleaseAge = 2880
autoInstallPeers = true
nodeLinker = "isolated"
packageImportMethod = "auto"
scpm reads configuration from .npmrc regardless of which tool wrote it.
Writes follow a routing rule: settings marked npmShared = true in
crates/scpm-settings/settings.toml (plus per-host auth/cert
templates and scoped registries) land in .npmrc so npm, yarn, and pnpm see
the same value. SCPM-only and pnpm-only settings land in
~/.config/scpm/config.toml instead, so unknown-to-npm keys don't trigger
warnings from sibling tools.
.npmrc
registry=https://registry.npmjs.org/
@mycorp:registry=https://npm.mycorp.internal/
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
https-proxy=http://corp-proxy:3128/
.npmrc holds the keys that npm, yarn, and pnpm all read: registries, scoped
registries, per-host auth, proxy/TLS, and the npm-standard scalars tagged
npmShared in the settings registry. scpm preserves symlinked .npmrc files
when it writes to one. See the settings reference — each entry
lists its .npmrc key alongside the other sources.
SCPM map settings (allowBuilds, overrides, packageExtensions, …) accept
dotted writes at project scope to edit one entry at a time:
scpm config set --local allowBuilds.@mongodb-js/zstd true
scpm config set --local overrides.lodash 4.17.21
The write lands in pnpm-workspace.yaml#<map>.<entry> when a workspace yaml
exists, otherwise package.json#scpm.<map>.<entry> — the same place install
reads from. User-scope dotted writes for these maps error: scpm only reads
them per project. For allowBuilds, scpm approve-builds <pkg> is the
interactive equivalent.
Workspace YAML
nodeLinker: isolated
minimumReleaseAge: 1440
publicHoistPattern:
- "*eslint*"
jailBuilds: true
jailBuildPermissions:
"@vendor/*":
env:
- SHARP_DIST_BASE_URL
write:
- ~/.cache/sharp
jailBuildExclusions:
- "@legacy-native/*"
See the settings reference — workspace YAML keys are listed per setting. The jail-related keys are described in Jailed builds.
Environment variables
pnpm-compatible NPM_CONFIG_* aliases are supported:
NPM_CONFIG_REGISTRY=https://registry.example.test scpm install
NPM_CONFIG_NODE_LINKER=hoisted scpm install
See the settings reference — environment variables are listed per setting.
CLI flags
CLI flags take precedence for the settings they expose:
scpm install --node-linker=hoisted
scpm install --network-concurrency=32
scpm install --resolution-mode=time-based
See the settings reference — CLI flags are listed per setting.
Inspecting config
scpm config get registry
scpm config set auto-install-peers false
scpm config list --json
Writes land in .npmrc only for the npm-shared surface (auth, registries,
npm-standard scalars). Everything else — scpm settings, pnpm-only knobs, and
unknown keys — is stored in scpm's own config. --local and
--location project write the project-scope equivalents (<cwd>/.npmrc and
<cwd>/.config/scpm/config.toml).
package.json — pnpm.* and scpm.* namespaces
scpm reads pnpm's package.json config keys so existing projects keep
working unchanged. Every key under pnpm.* is also accepted under
scpm.* for projects that want to declare scpm-native config without
piggy-backing on the pnpm namespace:
{
"scpm": {
"overrides": { "lodash": "4.17.21" },
"catalog": { "react": "^18.0.0" },
"supportedArchitectures": { "os": ["current", "linux"] },
"allowBuilds": { "sharp": true },
"patchedDependencies": { "foo@1.0.0": "patches/foo.patch" },
"peerDependencyRules": { "ignoreMissing": ["react-native"] }
}
}
Merge semantics when both namespaces are present:
- Map-valued keys (
overrides,catalog,catalogs,patchedDependencies,allowBuilds,allowedDeprecatedVersions,packageExtensions,peerDependencyRules.allowedVersions):scpm.*wins on key conflict; disjoint keys from either namespace merge. - List-valued keys (
onlyBuiltDependencies,neverBuiltDependencies,ignoredOptionalDependencies,peerDependencyRules.ignoreMissing,peerDependencyRules.allowAny,updateConfig.ignoreDependencies,supportedArchitectures.{os,cpu,libc}): entries from both namespaces union.onlyBuiltDependenciesandneverBuiltDependenciesare legacy build-policy inputs; new review state is written toallowBuilds. - Top-level npm-standard keys (
overrides,packageExtensions,allowedDeprecatedVersions,updateConfig) still take highest precedence, so thescpm.*alias doesn't change existing npm / pnpm precedence rules — it only adds a second namespace that beatspnpm.*but loses to the top-level form.
