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

node-gpg-wrapper

v0.1.8

Published

Node.js GPG Wrapper

Readme

node-gpg-wrapper

A tiny TypeScript wrapper around the gpg CLI for decrypting files in Node.js, with progress reporting and typed results.

What it does

  • Decrypts an encrypted file by streaming it into gpg
  • Returns plaintext in memory or writes directly to an output file
  • Reports progress (encryptedBytesRead, percent, status events)
  • Exposes structured decryption errors (GpgDecryptionError)
  • Ships a browser entrypoint that throws a clear "not supported" error

Install

npm i node-gpg-wrapper

Requirements:

  • Node.js >= 20
  • gpg installed and available in PATH (or pass a custom gpgPath)

Usage (Node)

import { GpgWrapper } from "node-gpg-wrapper";

const gpg = new GpgWrapper();

const result = await gpg.decryptFile({
  inputPath: "./secret.txt.gpg",
  passphrase: process.env.GPG_PASSPHRASE,
  // Either key text or a path to an armored private key file.
  privateKey: process.env.GPG_PRIVATE_KEY_PATH ?? process.env.GPG_PRIVATE_KEY,
  onProgress: (p) => {
    console.log(`${p.percent.toFixed(1)}%`, p.status ?? "");
  },
});

console.log(result.plaintext?.toString("utf8"));
console.log(result.durationMs);

Decrypt to disk instead of memory

const result = await gpg.decryptFile({
  inputPath: "./secret.txt.gpg",
  outputPath: "./secret.txt",
});

console.log(result.outputPath); // ./secret.txt
console.log(result.plaintext); // undefined

Browser entrypoint

import { decryptFile } from "node-gpg-wrapper/browser";

await decryptFile(); // throws BrowserNotSupportedError

Use the Node entrypoint for real decryption.

API

class GpgWrapper

  • decryptFile(options: DecryptFileOptions): Promise<DecryptResult>

GpgWrapper also emits a progress event with DecryptProgress.

DecryptFileOptions

  • inputPath: string (required)
  • outputPath?: string
  • passphrase?: string
  • privateKey?: string (ASCII-armored key text or path to key file)
  • gpgPath?: string (default: gpg)
  • homedir?: string
  • extraArgs?: string[]
  • onProgress?: (progress: DecryptProgress) => void
  • signal?: AbortSignal

DecryptProgress

  • encryptedBytesRead: number
  • encryptedTotalBytes: number
  • outputBytes: number
  • percent: number
  • status?: string (parsed from [GNUPG:] ... status lines)

DecryptResult

  • plaintext?: Buffer (only when outputPath is not set)
  • outputPath?: string
  • encryptedBytesRead: number
  • encryptedTotalBytes: number
  • outputBytes: number
  • durationMs: number
  • statusLines: string[]

GpgDecryptionError

Thrown when gpg exits with non-zero code.

Properties:

  • exitCode: number | null
  • stderr: string
  • statusLines: string[]

The error message now includes common root-cause hints (for example missing private key, missing/wrong passphrase, or invalid encrypted input) based on GPG status output and stderr.

Example:

gpg decrypt failed (exit code 2). No matching private key was found for this ciphertext. Hint: Provide the correct private key (and homedir) before decrypting. stderr: gpg: decryption failed: No secret key

Development

pnpm i
pnpm lint
pnpm test
pnpm build

Scripts:

  • pnpm dev - watch build
  • pnpm size - size-limit check for browser bundle

License

MIT