snpmv2026.5.16

Lockfile

snpm-lock.yaml schema, integrity markers, and lockfile imports

snpm-lock.yaml is snpm's native lockfile. It pins the exact resolved version, tarball, and integrity hash for every package in the dependency graph, making installs deterministic across machines and CI runners.

Schema

The lockfile is YAML and currently uses schema version 1.

snpm-lock.yaml
version: 1

root:
  dependencies:
    express:
      requested: "^4.18.0"
      version: 4.18.2
    typescript:
      requested: ^5.4.0
      version: 5.4.5
      optional: false

packages:
  express@4.18.2:
    name: express
    version: 4.18.2
    tarball: https://registry.npmjs.org/express/-/express-4.18.2.tgz
    integrity: sha512-...
    dependencies:
      body-parser: body-parser@1.20.1
      cookie: cookie@0.5.0
    hasBin: false

  body-parser@1.20.1:
    name: body-parser
    version: 1.20.1
    tarball: https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz
    integrity: sha512-...
    dependencies: {}

Key fields:

  • root.dependencies — direct dependencies declared in package.json. Each entry records the originally requested range plus the resolved version (and optional if the dep is optional).
  • packages.<name>@<version> — the resolved package. Stores name, version, tarball, integrity, transitive dependencies (map name → name@version of the resolved entry), bundledDependencies (if any), and hasBin / bin for packages that ship binaries.

Workspaces share a single snpm-lock.yaml at the workspace root.

When the lockfile is written

The lockfile updates whenever the install plan changes — snpm add, snpm remove, snpm upgrade, or snpm install with new packages.

snpm only writes a dev-inclusive lockfile when include_dev = true. With --production (or running an install path that skips dev), the existing lockfile is reused but not rewritten, so dev resolution does not get clobbered.

Frozen, prefer, fix

ModeCLI flagBehavior
Frozen--frozen-lockfile (alias --immutable), or SNPM_FROZEN_LOCKFILE=1Fail if the lockfile is missing or does not match the manifest.
No frozen--no-frozen-lockfileIgnore lockfile data and re-resolve.
Prefer--prefer-frozen-lockfileReuse lockfile entries that are still valid, re-resolve the rest.
Fix--fix-lockfile (install only)Re-resolve drifted entries while keeping unchanged ones pinned.

Pass these flags globally (snpm --frozen-lockfile install) and they propagate to every install-like subcommand, or pass them directly to the subcommand.

Integrity marker

After a successful install, snpm writes node_modules/.snpm-integrity containing a lockfile-derived hash. The next install reads this marker first and short-circuits if the hash still matches — that is the "hot install" path that completes in tens of milliseconds.

In workspaces, the integrity marker is written per project so changes to one project's deps don't invalidate the others.

Importing other lockfiles

When snpm-lock.yaml is missing, snpm can seed the first install from a compatible lockfile and then take over with its own format:

SourceFiles
pnpmpnpm-lock.yaml, branch lockfiles like pnpm-lock.feature!name.yaml
Bunbun.lock
Yarnyarn.lock
npmnpm-shrinkwrap.json, package-lock.json

Imported data is used only as compatibility input. Once the install completes, snpm-lock.yaml is the source of truth. Subsequent installs read snpm's lockfile.

Workspaces

A workspace has exactly one snpm-lock.yaml at the root — it covers every workspace project:

my-monorepo/
├── snpm-workspace.yaml
├── snpm-lock.yaml           ← single lockfile
├── packages/
│   ├── ui/package.json
│   └── utils/package.json
└── apps/
    └── web/package.json

Version control

Always commit snpm-lock.yaml.

It is small, human-readable, and the only guarantee that local builds match CI and production.

Merge conflicts

When you hit a conflict in snpm-lock.yaml:

  1. Resolve conflicts in every affected package.json first.
  2. Delete snpm-lock.yaml.
  3. Run snpm install.
git checkout --theirs package.json apps/*/package.json
# resolve manually if needed
rm snpm-lock.yaml
snpm install
git add snpm-lock.yaml

If you want to keep the existing resolution where possible, run snpm install --fix-lockfile instead — it only re-resolves entries that drifted.

Best practices

  • Always commit the lockfile.
  • Use --frozen-lockfile in CI — it catches missed commits and prevents quiet upgrades.
  • Review the diff in PRs — the YAML format makes it readable; new tarball URLs or integrity changes show up cleanly.
  • Prefer --fix-lockfile over deleting it when only a small subset of deps needs to be re-resolved.
  • Use snpm why <pkg> to trace why an unexpected package landed in the lockfile.

On this page