
Security News
Software Engineering Daily Podcast: Feross on AI, Open Source, and Supply Chain Risk
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.
@cnpmjs/packument
Advanced tools
@cnpmjs/packument@cnpmjs/packument is a package metadata helper for Node.js.
It provides a way to parse package metadata from buffer and diff versions between local and remote.
Based on sonic-rs to parse JSON efficiently.
yarn add @cnpmjs/packument
import { Package } from '@cnpmjs/packument'
import { readFileSync } from 'fs'
// Load package metadata from buffer
const buffer = readFileSync('path/to/packument.json')
const pkg = new Package(buffer)
// Get package information
console.log(pkg.name) // Package name
console.log(pkg.description) // Package description
console.log(pkg.readme) // Package readme
console.log(pkg.distTags) // { latest: '1.0.0', next: '2.0.0-beta.1' }
console.log(pkg.maintainers) // [{ name: 'foo', email: 'foo@example.com' }]
console.log(pkg.repository) // { type: 'git', url: 'https://github.com/...' }
console.log(pkg.time) // { created: '2020-01-01T00:00:00.000Z', modified: '2020-01-02T00:00:00.000Z', '1.0.0': '...' }
console.log(pkg.isUnpublished) // false
// Get latest version
const latestVersion = pkg.getLatestVersion()
console.log(latestVersion)
// Get all versions
const versions = pkg.versions
console.log(versions)
The diff method helps you find the difference between local package versions and remote package versions. This is useful for package synchronization scenarios.
import { Package } from '@cnpmjs/packument'
import { readFileSync } from 'fs'
// Prepare local and remote package data
const localVersions = ['1.0.0', '1.0.1', '1.0.2']
const remoteBuffer = readFileSync('path/to/remote-packument.json')
// Create remote package instance
const remotePkg = new Package(remoteBuffer)
// Find the diff
const diff = remotePkg.diff(localVersions)
console.log(diff.addedVersions) // Versions in remote but not in local
console.log(diff.removedVersions) // Versions in local but not in remote
// Example output:
// {
// addedVersions: [
// ['1.1.0', [100992, 119796]], // [version, [startPos, endPos]]
// ['1.2.0', [119797, 138592]],
// ],
// removedVersions: [
// '1.0.1', // This version exists in local but not in remote
// ]
// }
The addedVersions array includes position information (startPos, endPos) which allows you to extract the raw JSON metadata for each version directly from the buffer without parsing the entire package:
const diff = remotePkg.diff(localVersions)
// Extract version metadata from buffer using position
for (const [version, [start, end]] of diff.addedVersions) {
const versionMetadata = remoteBuffer.subarray(start, end)
const versionData = JSON.parse(versionMetadata)
console.log(`Version ${version}:`, versionData)
// versionData contains: name, version, dist, dependencies, etc.
}
This approach is much more efficient than parsing the entire package JSON when you only need specific version metadata.
The JSONBuilder class allows you to set or delete properties in a JSON buffer without parsing the entire document. This is useful for modifying large packument files efficiently.
import { JSONBuilder } from '@cnpmjs/packument'
import { readFileSync, writeFileSync } from 'fs'
const buffer = readFileSync('path/to/packument.json')
const builder = new JSONBuilder(buffer)
// Set a property using path array
builder.setIn(['dist-tags', 'latest'], '2.0.0')
// Add a new version
builder.setIn(['versions', '2.0.0'], {
name: 'my-package',
version: '2.0.0',
dist: {
shasum: 'abc123',
tarball: 'https://registry.npmjs.org/my-package/-/my-package-2.0.0.tgz',
},
})
// Delete a property
builder.deleteIn(['versions', '1.0.0-deprecated'])
// Delete with auto-cleanup of empty parent
builder.deleteIn(['versions', '0.0.1'], { autoDeleteParentIfEmpty: true })
// Get the modified buffer
const modifiedBuffer = builder.build()
writeFileSync('path/to/packument.json', modifiedBuffer)
Supported value types for setIn:
stringnumberbooleanDate (serialized to ISO string)object (serialized to JSON)npm run bench
βββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββ¬ββββββββββββββββββββββββ¬βββββββββββββββββββββββββ¬βββββββββββββββββββββββββ¬ββββββββββ
β (index) β Task name β Latency avg (ns) β Latency med (ns) β Throughput avg (ops/s) β Throughput med (ops/s) β Samples β
βββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββΌββββββββββββββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββββββββΌββββββββββ€
β 0 β 'JSONParse small data readme string (117KB)' β '266169 Β± 1.79%' β '256167 Β± 6458.0' β '3880 Β± 0.22%' β '3904 Β± 98' β 3758 β
β 1 β 'sonic-rs small data readme string (117KB)' β '96116 Β± 0.18%' β '93959 Β± 3334.0' β '10449 Β± 0.11%' β '10643 Β± 392' β 10405 β
β 2 β 'sonic-rs small data readme string with position (117KB)' β '104260 Β± 0.18%' β '101875 Β± 3541.0' β '9636 Β± 0.12%' β '9816 Β± 349' β 9592 β
β 3 β 'sonic-rs small data readme JSON buffer with position (117KB)' β '80798 Β± 0.10%' β '78125 Β± 1250.0' β '12415 Β± 0.09%' β '12800 Β± 202' β 12377 β
β 4 β 'JSONParse large data readme string (22MB)' β '61213649 Β± 0.46%' β '60913854 Β± 457520' β '16 Β± 0.46%' β '16 Β± 0' β 64 β
β 5 β 'sonic-rs large data readme string (22MB)' β '14408984 Β± 0.77%' β '14446271 Β± 314188' β '69 Β± 0.77%' β '69 Β± 2' β 70 β
β 6 β 'sonic-rs large data readme string with position (22MB)' β '14422542 Β± 0.82%' β '14286833 Β± 445437' β '69 Β± 0.81%' β '70 Β± 2' β 70 β
β 7 β 'sonic-rs large data readme JSON buffer with position (22MB)' β '14601161 Β± 0.90%' β '14690709 Β± 292041' β '69 Β± 0.90%' β '68 Β± 1' β 69 β
β 8 β 'JSONParse super large data readme string (89M)' β '156435868 Β± 1.25%' β '152015667 Β± 2226000' β '6 Β± 1.21%' β '7 Β± 0' β 64 β
β 9 β 'sonic-rs super large data readme string (89M)' β '52196231 Β± 0.78%' β '51696729 Β± 991125' β '19 Β± 0.77%' β '19 Β± 0' β 64 β
β 10 β 'sonic-rs super large data readme string with position (89M)' β '52017035 Β± 0.87%' β '51689855 Β± 1427041' β '19 Β± 0.86%' β '19 Β± 1' β 64 β
β 11 β 'sonic-rs super large data readme JSON buffer with position (89M)' β '52177505 Β± 0.85%' β '51624876 Β± 1226542' β '19 Β± 0.83%' β '19 Β± 0' β 64 β
β 12 β 'JSONParse big readme string (229KB, 64KB readme)' β '335244 Β± 1.66%' β '323958 Β± 6624.0' β '3071 Β± 0.26%' β '3087 Β± 63' β 2983 β
β 13 β 'sonic-rs big readme string (229KB, 64KB readme)' β '146211 Β± 0.21%' β '147375 Β± 4500.0' β '6867 Β± 0.13%' β '6785 Β± 209' β 6840 β
β 14 β 'sonic-rs big readme string with position (229KB, 64KB readme)' β '173274 Β± 0.19%' β '173729 Β± 5771.0' β '5791 Β± 0.14%' β '5756 Β± 192' β 5772 β
β 15 β 'sonic-rs big readme JSON buffer with position (229KB, 64KB readme)' β '126633 Β± 0.13%' β '127208 Β± 5292.0' β '7922 Β± 0.12%' β '7861 Β± 331' β 7897 β
βββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββ΄ββββββββββββββββββββββββ΄βββββββββββββββββββββββββ΄βββββββββββββββββββββββββ΄ββββββββββ
Memory Usage:
JSONParse description (22M): 478.1 MB (min: 477.9 MB, max: 478.5 MB)
JSONParse description (89M): 792.1 MB (min: 791.5 MB, max: 792.9 MB)
SonicJSONParse description (22M): 91.4 MB (min: 91.2 MB, max: 91.6 MB)
SonicJSONParse description (89M): 158.5 MB (min: 158.3 MB, max: 158.6 MB)
βββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββ¬βββββββββββββββββββββββββ¬βββββββββββββββββββββββββ¬βββββββββββββββββββββββββ¬ββββββββββ
β (index) β Task name β Latency avg (ns) β Latency med (ns) β Throughput avg (ops/s) β Throughput med (ops/s) β Samples β
βββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββββββββΌββββββββββ€
β 0 β 'JSONParse small data readme string (117KB)' β '259742 Β± 0.52%' β '247230 Β± 8917.0' β '3913 Β± 0.34%' β '4045 Β± 149' β 3850 β
β 1 β 'sonic-rs small data readme string (117KB)' β '98949 Β± 0.29%' β '98417 Β± 4999.0' β '10189 Β± 0.14%' β '10161 Β± 515' β 10107 β
β 2 β 'sonic-rs small data readme string with position (117KB)' β '107065 Β± 0.22%' β '105917 Β± 5249.0' β '9404 Β± 0.14%' β '9441 Β± 456' β 9341 β
β 3 β 'sonic-rs small data readme JSON buffer with position (117KB)' β '86159 Β± 0.49%' β '87666 Β± 1084.0' β '11706 Β± 0.12%' β '11407 Β± 143' β 11607 β
β 4 β 'JSONParse large data readme string (22MB)' β '76834607 Β± 5.25%' β '66358500 Β± 2121250' β '14 Β± 4.62%' β '15 Β± 0' β 64 β
β 5 β 'sonic-rs large data readme string (22MB)' β '14920809 Β± 0.71%' β '14854833 Β± 258396' β '67 Β± 0.69%' β '67 Β± 1' β 68 β
β 6 β 'sonic-rs large data readme string with position (22MB)' β '15473730 Β± 0.91%' β '15392875 Β± 346958' β '65 Β± 0.83%' β '65 Β± 1' β 65 β
β 7 β 'sonic-rs large data readme JSON buffer with position (22MB)' β '15280011 Β± 0.88%' β '15226563 Β± 385272' β '66 Β± 0.88%' β '66 Β± 2' β 66 β
β 8 β 'JSONParse super large data readme string (89M)' β '166472681 Β± 2.56%' β '159452958 Β± 12719146' β '6 Β± 2.52%' β '6 Β± 1' β 64 β
β 9 β 'sonic-rs super large data readme string (89M)' β '55477295 Β± 0.58%' β '55223313 Β± 914063' β '18 Β± 0.57%' β '18 Β± 0' β 64 β
β 10 β 'sonic-rs super large data readme string with position (89M)' β '54809802 Β± 0.53%' β '54409938 Β± 633917' β '18 Β± 0.52%' β '18 Β± 0' β 64 β
β 11 β 'sonic-rs super large data readme JSON buffer with position (89M)' β '54798735 Β± 0.65%' β '54398208 Β± 554979' β '18 Β± 0.61%' β '18 Β± 0' β 64 β
β 12 β 'JSONParse big readme string (229KB, 64KB readme)' β '332583 Β± 1.01%' β '318792 Β± 6709.0' β '3091 Β± 0.36%' β '3137 Β± 67' β 3007 β
β 13 β 'sonic-rs big readme string (229KB, 64KB readme)' β '154914 Β± 0.66%' β '152417 Β± 2875.0' β '6549 Β± 0.20%' β '6561 Β± 123' β 6456 β
β 14 β 'sonic-rs big readme string with position (229KB, 64KB readme)' β '185652 Β± 0.74%' β '180625 Β± 5834.0' β '5499 Β± 0.27%' β '5536 Β± 179' β 5387 β
β 15 β 'sonic-rs big readme JSON buffer with position (229KB, 64KB readme)' β '134273 Β± 0.60%' β '133083 Β± 1666.0' β '7521 Β± 0.16%' β '7514 Β± 93' β 7448 β
β 16 β 'JSONParse large data add version (22MB)' β '141596438 Β± 3.18%' β '130096250 Β± 3036583' β '7 Β± 2.94%' β '8 Β± 0' β 64 β
β 17 β 'sonic-rs large data add version (22MB)' β '47422600 Β± 0.46%' β '47358021 Β± 578896' β '21 Β± 0.46%' β '21 Β± 0' β 64 β
β 18 β 'JSONParse super large data add version (89M)' β '395517850 Β± 0.63%' β '393929666 Β± 6207959' β '3 Β± 0.61%' β '3 Β± 0' β 64 β
β 19 β 'sonic-rs super large data add version (89M)' β '170208911 Β± 0.46%' β '170423042 Β± 2301708' β '6 Β± 0.46%' β '6 Β± 0' β 64 β
βββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββ΄βββββββββββββββββββββββββ΄βββββββββββββββββββββββββ΄βββββββββββββββββββββββββ΄ββββββββββ
Memory Usage:
JSONParse description (22M): 343.4 MB (min: 343.2 MB, max: 343.8 MB)
JSONParse description (89M): 577.1 MB (min: 576.5 MB, max: 577.7 MB)
SonicJSONParse description (22M): 81.3 MB (min: 81.1 MB, max: 81.8 MB)
SonicJSONParse description (89M): 148.8 MB (min: 148.5 MB, max: 149.2 MB)
Memory Usage:
JSONParse add version (22M): 463.9 MB (min: 462.3 MB, max: 466.6 MB)
JSONParse add version (89M): 726.5 MB (min: 723.6 MB, max: 730.4 MB)
SonicJSONParse add version (22M): 133.1 MB (min: 128.5 MB, max: 151.0 MB)
SonicJSONParse add version (89M): 417.8 MB (min: 417.8 MB, max: 417.9 MB)
$ npx tsx benchmark/bench.ts
βββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββ¬βββββββββββββββββββββββββ¬βββββββββββββββββββββββββ¬βββββββββββββββββββββββββ¬ββββββββββ
β (index) β Task name β Latency avg (ns) β Latency med (ns) β Throughput avg (ops/s) β Throughput med (ops/s) β Samples β
βββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββββββββΌββββββββββ€
β 0 β 'JSONParse small data readme string (117KB)' β '282642 Β± 0.87%' β '272875 Β± 8667.0' β '3626 Β± 0.33%' β '3665 Β± 115' β 3539 β
β 1 β 'sonic-rs small data readme string (117KB)' β '97086 Β± 0.17%' β '96416 Β± 5042.0' β '10353 Β± 0.12%' β '10372 Β± 537' β 10301 β
β 2 β 'sonic-rs small data readme string with position (117KB)' β '106532 Β± 0.49%' β '105209 Β± 5584.0' β '9486 Β± 0.15%' β '9505 Β± 509' β 9387 β
β 3 β 'sonic-rs small data readme JSON buffer with position (117KB)' β '81501 Β± 0.11%' β '79625 Β± 2708.0' β '12312 Β± 0.10%' β '12559 Β± 442' β 12270 β
β 4 β 'JSONParse large data readme string (22MB)' β '81700227 Β± 3.67%' β '74035333 Β± 1724355' β '12 Β± 3.35%' β '14 Β± 0' β 64 β
β 5 β 'sonic-rs large data readme string (22MB)' β '14406041 Β± 0.58%' β '14339813 Β± 245083' β '69 Β± 0.57%' β '70 Β± 1' β 70 β
β 6 β 'sonic-rs large data readme string with position (22MB)' β '14373543 Β± 0.47%' β '14350042 Β± 98937' β '70 Β± 0.46%' β '70 Β± 0' β 70 β
β 7 β 'sonic-rs large data readme JSON buffer with position (22MB)' β '14372198 Β± 0.52%' β '14351229 Β± 96354' β '70 Β± 0.52%' β '70 Β± 0' β 70 β
β 8 β 'JSONParse super large data readme string (89M)' β '192673340 Β± 1.78%' β '201564354 Β± 19275396' β '5 Β± 1.75%' β '5 Β± 1' β 64 β
β 9 β 'sonic-rs super large data readme string (89M)' β '51303309 Β± 0.60%' β '51097167 Β± 809375' β '20 Β± 0.59%' β '20 Β± 0' β 64 β
β 10 β 'sonic-rs super large data readme string with position (89M)' β '51120106 Β± 0.44%' β '50995396 Β± 506500' β '20 Β± 0.43%' β '20 Β± 0' β 64 β
β 11 β 'sonic-rs super large data readme JSON buffer with position (89M)' β '51319434 Β± 0.44%' β '51296937 Β± 428146' β '19 Β± 0.43%' β '19 Β± 0' β 64 β
β 12 β 'JSONParse big readme string (229KB, 64KB readme)' β '339916 Β± 0.59%' β '331250 Β± 6375.0' β '2985 Β± 0.33%' β '3019 Β± 58' β 2942 β
β 13 β 'sonic-rs big readme string (229KB, 64KB readme)' β '145951 Β± 0.21%' β '147000 Β± 4167.0' β '6881 Β± 0.14%' β '6803 Β± 193' β 6852 β
β 14 β 'sonic-rs big readme string with position (229KB, 64KB readme)' β '171549 Β± 0.22%' β '170541 Β± 7417.0' β '5858 Β± 0.16%' β '5864 Β± 248' β 5830 β
β 15 β 'sonic-rs big readme JSON buffer with position (229KB, 64KB readme)' β '125563 Β± 0.19%' β '125875 Β± 5500.0' β '7994 Β± 0.12%' β '7944 Β± 345' β 7965 β
βββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββ΄βββββββββββββββββββββββββ΄βββββββββββββββββββββββββ΄βββββββββββββββββββββββββ΄ββββββββββ
Memory Usage:
JSONParse description (22M): 406.0 MB (min: 392.1 MB, max: 498.3 MB)
JSONParse description (89M): 659.6 MB (min: 594.5 MB, max: 987.7 MB)
SonicJSONParse description (22M): 179.7 MB (min: 177.0 MB, max: 181.3 MB)
SonicJSONParse description (89M): 179.3 MB (min: 175.2 MB, max: 181.8 MB)
After npm run build command, you can see packument.[darwin|win32|linux].node file in project root. This is the native addon built from lib.rs.
With vitest, run npm test to testing native addon.
With GitHub Actions, each commit and pull request will be built and tested automatically in [node@20, @node22] x [macOS, Linux, Windows] matrix. You will never be afraid of the native addon broken in these platforms.
Release native package is very difficult in old days. Native packages may ask developers who use it to install build toolchain like gcc/llvm, node-gyp or something more.
With GitHub actions, we can easily prebuild a binary for major platforms. And with N-API, we should never be afraid of ABI Compatible.
The other problem is how to deliver prebuild binary to users. Downloading it in postinstall script is a common way that most packages do it right now. The problem with this solution is it introduced many other packages to download binary that has not been used by runtime codes. The other problem is some users may not easily download the binary from GitHub/CDN if they are behind a private network (But in most cases, they have a private NPM mirror).
In this package, we choose a better way to solve this problem. We release different npm packages for different platforms. And add it to optionalDependencies before releasing the Major package to npm.
NPM will choose which native package should download from registry automatically. You can see npm dir for details. And you can also run yarn add @napi-rs/package-template to see how it works.
RustNode.js@10+ which fully supported Node-APIyarn@1.xWhen you want to release the package:
npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease [--preid=<prerelease-id>] | from-git]
git push origin master --tags
GitHub actions will do the rest job for you.
WARN: Don't run
npm publishmanually.
Made with contributors-img.
FAQs
Packument helper
The npm package @cnpmjs/packument receives a total of 1,535 weekly downloads. As such, @cnpmjs/packument popularity was classified as popular.
We found that @cnpmjs/packument demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 5 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.

Security News
GitHub has revoked npm classic tokens for publishing; maintainers must migrate, but OpenJS warns OIDC trusted publishing still has risky gaps for critical projects.

Security News
Rustβs crates.io team is advancing an RFC to add a Security tab that surfaces RustSec vulnerability and unsoundness advisories directly on crate pages.