🚨 Shai-Hulud Strikes Again:834 Packages Compromised.Technical Analysis β†’
Socket
Book a DemoInstallSign in
Socket

@cnpmjs/packument

Package Overview
Dependencies
Maintainers
5
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cnpmjs/packument

Packument helper

latest
Source
npmnpm
Version
1.5.0
Version published
Maintainers
5
Created
Source

@cnpmjs/packument

CI Node.js Version PRs Welcome CodeRabbit Pull Request Reviews NPM Version NPM Downloads NPM License

@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.

Features

  • Parse package metadata from buffer
  • Diff versions between local and remote
  • Extract version metadata using position
  • Set property without parsing
  • Delete property without parsing
  • Add value to Array property without parsing

Install

yarn add @cnpmjs/packument

Usage

Basic Usage

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)

Diff Versions Between Local and Remote

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
//   ]
// }

Extract Version Metadata Using Position

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.

Modify JSON Without Full Parsing (JSONBuilder)

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:

  • string
  • number
  • boolean
  • Date (serialized to ISO string)
  • object (serialized to JSON)

Benchmark

npm run bench

Node.js v24.11.1 Result

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ (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)

Node.js v22.21.1 Result

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ (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)

Node.js 20.19.5 Result

$ 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)

Ability

Build

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.

Test

With vitest, run npm test to testing native addon.

CI

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

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.

Develop requirements

  • Install the latest Rust
  • Install Node.js@10+ which fully supported Node-API
  • Install yarn@1.x

Test in local

  • yarn
  • yarn build
  • yarn test

Release package

When 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 publish manually.

License

MIT

Contributors

Contributors

Made with contributors-img.

Keywords

napi-rs

FAQs

Package last updated on 06 Dec 2025

Did you know?

Socket

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.

Install

Related posts