npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nodearchive/nodearchive

v1.0.0

Published

Pack and unpack nar, zip, tar, tgz, tar.gz, and gz archives from one API and CLI for Node.js and Bun.

Downloads

31

Readme

npm version CI codecov license

nodearchive

nodearchive packs and unpacks .nar, .zip, .tar, .tgz, .tar.gz, and .gz from one package surface for ESM, CommonJS, Bun, and the nar CLI. Use it when a JavaScript build, release, or vendor-import flow needs one archive tool instead of a stack of one-format packages.

Install

npm install @nodearchive/nodearchive
pnpm add @nodearchive/nodearchive
yarn add @nodearchive/nodearchive
bun add @nodearchive/nodearchive

Global CLI:

npm install --global @nodearchive/nodearchive
# or
bun add --global @nodearchive/nodearchive

Run once without a global install:

npx @nodearchive/nodearchive pack --help
bunx @nodearchive/nodearchive unpack --help

Quick start

CLI:

npm i -g @nodearchive/nodearchive
nar --help

nar pack ./src ./app.nar
nar unpack ./incoming.zip ./vendor

Code:

import { pack, unpack } from '@nodearchive/nodearchive'

await pack({ literalPath: ['src'], destinationPath: './app.nar' })
await unpack({ path: './incoming.zip', destinationPath: './vendor' })

CommonJS:

const { pack, unpack } = require('@nodearchive/nodearchive')

async function main() {
  const archive = await pack({ blob: 'hello world' })
  const restored = await unpack({ blob: archive })

  console.log(Buffer.from(restored).toString('utf8'))
}

main()

Formats and runtime support

  • Writes: .nar, .zip, .tar, .tgz, .tar.gz, and .gz
  • Reads: .nar, .zip, .tar, .tgz, .tar.gz, and .gz
  • Runtimes: Node >= 18 and Bun
  • Package entry points: ESM import and CommonJS require()
  • CLI: nar
  • Inputs: glob paths, exact paths, and in-memory bytes
  • Outputs: filesystem writes or memory return values

Examples

Filesystem output

import { pack, unpack } from '@nodearchive/nodearchive'

await pack({
  literalPath: ['src', 'package.json'],
  destinationPath: './dist/app.nar',
  force: true,
})

await unpack({
  path: './dist/app.nar',
  destinationPath: './out',
  force: true,
})

In-memory bytes

import { pack, unpack } from '@nodearchive/nodearchive'

const archive = await pack({ blob: 'hello world' })
const restored = await unpack({ blob: archive })

console.log(Buffer.from(restored).toString('utf8'))

CommonJS

const { pack, unpack } = require('@nodearchive/nodearchive')

async function main() {
  const archive = await pack({ literalPath: ['src'] })
  const restored = await unpack({ blob: archive })

  console.log(restored.entries.length)
}

main()

Alternative output formats

import { pack } from '@nodearchive/nodearchive'

await pack({
  literalPath: ['src'],
  destinationPath: './dist/app.zip',
  outFormat: 'zip',
})

await pack({
  literalPath: ['src'],
  destinationPath: './dist/app.tgz',
})

Incoming zip or tarball

import { unpack } from '@nodearchive/nodearchive'

await unpack({
  path: './vendor/release.tar.gz',
  destinationPath: './vendor/release',
  force: true,
})

CLI

nar pack ./src ./dist/app.nar --passThru
nar pack ./src ./dist/app.zip --outFormat zip --passThru
nar unpack ./dist/app.nar ./out --force --passThru
nar unpack ./incoming.zip ./out --force
nar pack --help
npx @nodearchive/nodearchive pack --help
bunx @nodearchive/nodearchive unpack --help

Behavior

  • pack() writes .nar, .zip, .tar, .tgz, .tar.gz, and .gz.
  • unpack() reads .nar, .zip, .tar, .tgz, .tar.gz, and .gz.
  • outFormat selects the output archive type. destinationPath also infers the format from supported extensions.
  • .gz output is limited to a single input. update is limited to native .nar output.
  • In-memory mode accepts strings, blobs, typed arrays, ArrayBuffer, and SharedArrayBuffer.
  • path uses glob expansion through fast-glob; literalPath stays exact.
  • Validation failures throw NodearchiveError codes such as ARCHIVE_INPUT_REQUIRED, ARCHIVE_INVALID_FORMAT, ARCHIVE_DESTINATION_EXISTS, and ARCHIVE_ENTRY_PATH_INVALID.
  • Unsafe extraction paths and unsupported entry types are rejected instead of being silently rewritten.

Reference

Quality signals

  • Suite: unit + integration (Node), E2E (Playwright), Bun smoke
  • Matrix: Node 18 / 20 / 22; Chromium / Firefox / WebKit plus mobile emulation
  • Coverage: c8 at 100% statements, branches, functions, and lines
  • Reports: coverage/lcov.info and coverage/index.html

Benchmarks

Command: npm run bench Environment: Node v22.14.0 on win32 x64

| Benchmark | Result | | ---------------- | ---------------------------- | | pack blob | 3,170.28 ops/s (126.17 ms) | | unpack blob | 3,306.20 ops/s (120.98 ms) | | pack directory | 309.35 ops/s (387.91 ms) | | unpack archive | 4,109.76 ops/s (29.20 ms) |

Results vary by machine.

License

Apache-2.0