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-wrapperRequirements:
- Node.js
>= 20 gpginstalled and available inPATH(or pass a customgpgPath)
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); // undefinedBrowser entrypoint
import { decryptFile } from "node-gpg-wrapper/browser";
await decryptFile(); // throws BrowserNotSupportedErrorUse 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?: stringpassphrase?: stringprivateKey?: string(ASCII-armored key text or path to key file)gpgPath?: string(default:gpg)homedir?: stringextraArgs?: string[]onProgress?: (progress: DecryptProgress) => voidsignal?: AbortSignal
DecryptProgress
encryptedBytesRead: numberencryptedTotalBytes: numberoutputBytes: numberpercent: numberstatus?: string(parsed from[GNUPG:] ...status lines)
DecryptResult
plaintext?: Buffer(only whenoutputPathis not set)outputPath?: stringencryptedBytesRead: numberencryptedTotalBytes: numberoutputBytes: numberdurationMs: numberstatusLines: string[]
GpgDecryptionError
Thrown when gpg exits with non-zero code.
Properties:
exitCode: number | nullstderr: stringstatusLines: 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 keyDevelopment
pnpm i
pnpm lint
pnpm test
pnpm buildScripts:
pnpm dev- watch buildpnpm size- size-limit check for browser bundle
License
MIT
