Utilities for parsing and working with npm ecosystem lockfiles.
Supports npm, yarn, pnpm, bun (including binary .lockb), and vlt lockfiles.
npm install lockfile-tools
import { PACKAGE_MANAGERS } from 'lockfile-tools/package-managers';
console.log(PACKAGE_MANAGERS.npm);
// { lockfiles: ['package-lock.json', 'npm-shrinkwrap.json'], defaultLockfile: 'package-lock.json' }
console.log(PACKAGE_MANAGERS.yarn);
// { lockfiles: ['yarn.lock'], defaultLockfile: 'yarn.lock' }
Available package managers: npm, yarn, pnpm, bun, vlt
import {
loadLockfileContent,
loadBunLockbContent,
getLockfileName,
findJsonKeyLine,
} from 'lockfile-tools/io';
// Load lockfile content as string
const content = loadLockfileContent('/path/to/package-lock.json');
// Load binary bun.lockb files (converts to yarn.lock format)
const bunContent = loadBunLockbContent('/path/to/bun.lockb');
// Get lockfile basename
const name = getLockfileName('/path/to/package-lock.json');
// 'package-lock.json'
// Find line number of a JSON key
const line = findJsonKeyLine(content, 'node_modules/tape');
// 42
import {
parseYarnLockfile,
parsePnpmLockfile,
createLockfileExtractor,
} from 'lockfile-tools/parsers';
// Parse yarn.lock
const yarnEntries = parseYarnLockfile(content, ['resolved', 'integrity']);
// [{ name: 'pkg@^1.0.0', resolved: 'https://...', integrity: 'sha512-...', line: 5 }]
// Parse pnpm-lock.yaml
const pnpmEntries = parsePnpmLockfile(content, ['tarball', 'integrity']);
// [{ name: 'pkg@1.0.0', resolved: 'https://...', integrity: 'sha512-...', line: 10 }]
// Create a generic extractor that handles all formats
const extract = createLockfileExtractor({
'package-lock.json': (content) => extractFromNpm(content),
'yarn.lock': (content) => parseYarnLockfile(content, ['resolved']),
// ... other formats
}, bunLockbExtractor);
import {
normalizeRegistry,
extractRegistryFromUrl,
} from 'lockfile-tools/registry';
// Normalize registry URL
normalizeRegistry('https://registry.npmjs.org/');
// 'https://registry.npmjs.org'
// Extract registry from tarball URL
extractRegistryFromUrl('https://registry.npmjs.org/tape/-/tape-5.0.0.tgz');
// 'https://registry.npmjs.org'
// Works with path-based registries too
extractRegistryFromUrl('https://artifacts.example.com/api/npm/repo/tape/-/tape-5.0.0.tgz');
// 'https://artifacts.example.com/api/npm/repo'
import {
traverseDependencies,
extractPackageName,
} from 'lockfile-tools/npm';
// Traverse npm lockfile v1 dependencies recursively
traverseDependencies(deps, (name, dep) => {
console.log(name, dep.version, dep.resolved);
});
// Extract package name from lockfile key
extractPackageName('node_modules/@scope/package-name');
// '@scope/package-name'
When no physical lockfile exists, generate a virtual one using @npmcli/arborist:
import {
hasLockfile,
buildVirtualLockfile,
} from 'lockfile-tools/virtual';
// Check if any lockfile exists
if (!hasLockfile('/path/to/project')) {
// Build virtual lockfile from package.json + node_modules
const packages = await buildVirtualLockfile('/path/to/project');
// [{ name: 'tape', version: '5.0.0', resolved: 'https://...', integrity: 'sha512-...', isDirect: true }]
}
This package provides the following subpath exports:
| Export | Description |
|---|---|
lockfile-tools/package-managers | Package manager definitions and lockfile names |
lockfile-tools/io | File I/O operations |
lockfile-tools/parsers | Lockfile format parsers |
lockfile-tools/registry | Registry URL utilities |
lockfile-tools/npm | npm lockfile-specific utilities |
lockfile-tools/virtual | Virtual lockfile generation via arborist |
| Package Manager | Lockfile(s) |
|---|---|
| npm | package-lock.json, npm-shrinkwrap.json |
| yarn | yarn.lock (v1 and v2) |
| pnpm | pnpm-lock.yaml |
| bun | bun.lock, bun.lockb (binary) |
| vlt | vlt-lock.json |
Clone the repo, npm install, and run npm test.
MIT