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

@happyvertical/encryption

v0.111.5

Published

Unified encryption and cryptography operations with adapter-based architecture

Readme

@happyvertical/encryption

Unified encryption and cryptography operations with adapter-based architecture supporting PGP, NaCl, and Node.js crypto.

Tests License TypeScript

Features

  • 🔐 Multiple Encryption Methods: PGP/OpenPGP, NaCl/libsodium, Node.js crypto
  • 📝 Text, Files & Buffers: Encrypt any data format with a unified API
  • 📧 Email Integration: Specialized PGP/MIME email encryption
  • 🔑 Key Management: Generate, import, export, and manage encryption keys
  • ✍️ Digital Signatures: Sign and verify data with RSA, ECDSA, and EdDSA
  • 🎯 Type-Safe: Full TypeScript support with comprehensive type definitions
  • ⚡ High Performance: Fast NaCl encryption, efficient streaming for large files
  • 🧪 Well-Tested: 209 tests covering all adapters and use cases

Installation

npm install @happyvertical/encryption
# or
pnpm add @happyvertical/encryption
# or
yarn add @happyvertical/encryption

Claude Code Context

Install Claude Code context files for AI-assisted development:

npx have-encryption-context

This copies the package's AGENT.md documentation and metadata.json metadata to your project's .claude/ directory, enabling Claude to provide better assistance when working with this package.

Quick Start

PGP Encryption

import { getEncryption } from '@happyvertical/encryption';

// Create PGP encryption instance
const pgp = await getEncryption({ type: 'pgp' });

// Generate keypair
const keypair = await pgp.generateKeyPair({
  name: 'Alice',
  email: '[email protected]',
  passphrase: 'secure-passphrase',
  type: 'rsa',
  keySize: 4096
});

// Initialize with keys
const encryption = await getEncryption({
  type: 'pgp',
  publicKey: keypair.publicKey,
  privateKey: keypair.privateKey,
  passphrase: 'secure-passphrase'
});

// Encrypt and decrypt text
const encrypted = await encryption.encryptText('Secret message');
const decrypted = await encryption.decryptText(encrypted);

// Encrypt and decrypt files
await encryption.encryptFile('document.pdf', 'document.pdf.pgp');
await encryption.decryptFile('document.pdf.pgp', 'document.pdf');

NaCl Encryption (Fast & Modern)

import { getEncryption } from '@happyvertical/encryption';

// Generate keypair
const nacl = await getEncryption({ type: 'nacl' });
const keypair = await nacl.generateKeyPair();

// Symmetric encryption (secretbox)
const encryption = await getEncryption({
  type: 'nacl',
  secretKey: keypair.secretKey
});

const encrypted = await encryption.encryptText('Secret message');
const decrypted = await encryption.decryptText(encrypted);

// Encrypt files (very fast!)
await encryption.encryptFile('data.json', 'data.json.enc');
await encryption.decryptFile('data.json.enc', 'data.json');

Node.js Crypto (AES & RSA)

import { getEncryption } from '@happyvertical/encryption';

// AES-256-GCM encryption
const aes = await getEncryption({
  type: 'node',
  algorithm: 'aes-256-gcm',
  keyDerivation: {
    password: 'user-password',
    salt: 'unique-salt',
    iterations: 100000
  }
});

const encrypted = await aes.encryptText('Secret message');
const decrypted = await aes.decryptText(encrypted);

// RSA encryption
const rsa = await getEncryption({
  type: 'node',
  algorithm: 'rsa-oaep'
});

const keypair = await rsa.generateKeyPair({
  type: 'rsa',
  keySize: 2048
});

const rsaEncryption = await getEncryption({
  type: 'node',
  algorithm: 'rsa-oaep',
  publicKey: keypair.publicKey,
  privateKey: keypair.privateKey
});

const encrypted = await rsaEncryption.encryptText('Small message');
const decrypted = await rsaEncryption.decryptText(encrypted);

Common Use Cases

Email Encryption (PGP/MIME)

import { getEncryption } from '@happyvertical/encryption';

const pgp = await getEncryption({
  type: 'pgp',
  publicKey: recipientPublicKey,
  privateKey: myPrivateKey,
  passphrase: 'my-passphrase'
});

// Encrypt email message
const encryptedEmail = await pgp.encryptEmail({
  from: { address: '[email protected]' },
  to: [{ address: '[email protected]' }],
  subject: 'Confidential Information',
  text: 'Secret message content',
  attachments: [
    { filename: 'document.pdf', content: pdfBuffer }
  ]
}, {
  sign: true,
  armor: true
});

// Send with your email provider
// await mailbox.send(encryptedEmail);

Database Field Encryption

import { getEncryption } from '@happyvertical/encryption';

const encryption = await getEncryption({
  type: 'node',
  algorithm: 'aes-256-gcm',
  keyDerivation: {
    password: process.env.DB_ENCRYPTION_PASSWORD,
    salt: 'db-encryption-salt',
    iterations: 100000
  }
});

// Encrypt sensitive fields
async function saveUser(user) {
  const encryptedSSN = await encryption.encryptText(user.ssn);
  const encryptedCreditCard = await encryption.encryptText(user.creditCard);

  await db.insert('users', {
    id: user.id,
    name: user.name,  // Plain text
    ssn: encryptedSSN,
    credit_card: encryptedCreditCard
  });
}

// Decrypt when retrieving
async function getUser(id) {
  const row = await db.selectOne('users', { where: { id } });

  return {
    id: row.id,
    name: row.name,
    ssn: await encryption.decryptText(row.ssn),
    creditCard: await encryption.decryptText(row.credit_card)
  };
}

File Backup Encryption

import { getEncryption } from '@happyvertical/encryption';

const encryption = await getEncryption({
  type: 'nacl',
  secretKey: backupSecretKey
});

// Encrypt backup files
await encryption.encryptFile(
  '/data/backup-2024-01.tar.gz',
  '/encrypted-backups/backup-2024-01.tar.gz.enc'
);

// Decrypt when needed
await encryption.decryptFile(
  '/encrypted-backups/backup-2024-01.tar.gz.enc',
  '/restored/backup-2024-01.tar.gz'
);

Digital Signatures

import { getEncryption } from '@happyvertical/encryption';

const pgp = await getEncryption({
  type: 'pgp',
  privateKey: myPrivateKey,
  passphrase: 'my-passphrase'
});

// Sign message
const message = 'Important announcement';
const signature = await pgp.sign(message, {
  detached: true,
  armor: true
});

// Verify signature
const valid = await pgp.verify(message, signature, {
  publicKey: signerPublicKey
});

if (valid) {
  console.log('✓ Signature verified - message is authentic');
} else {
  console.log('✗ Invalid signature - message may be tampered');
}

API Overview

Factory Function

function getEncryption(options: GetEncryptionOptions): Promise<Encryption>

Encryption Interface

All adapters implement this unified interface:

interface Encryption {
  // Text operations
  encryptText(text: string, options?: EncryptOptions): Promise<string>;
  decryptText(encrypted: string, options?: DecryptOptions): Promise<string>;

  // File operations
  encryptFile(inputPath: string, outputPath: string, options?: EncryptOptions): Promise<void>;
  decryptFile(inputPath: string, outputPath: string, options?: DecryptOptions): Promise<void>;

  // Buffer operations
  encryptBuffer(buffer: Buffer, options?: EncryptOptions): Promise<Buffer>;
  decryptBuffer(buffer: Buffer, options?: DecryptOptions): Promise<Buffer>;

  // Key management
  generateKeyPair(options?: KeyPairOptions): Promise<KeyPair>;
  importKey(key: string | Buffer, options?: ImportKeyOptions): Promise<Key>;
  exportKey(key: Key, options?: ExportKeyOptions): Promise<string | Buffer>;

  // Signing (optional)
  sign?(data: string | Buffer, options?: SignOptions): Promise<string | Buffer>;
  verify?(data: string | Buffer, signature: string | Buffer, options?: VerifyOptions): Promise<boolean>;

  // Email operations (PGP only)
  encryptEmail?(message: EmailMessage, options?: EncryptEmailOptions): Promise<EmailMessage>;
  decryptEmail?(message: EmailMessage, options?: DecryptEmailOptions): Promise<DecryptedEmail>;

  // Adapter info
  getCapabilities(): Promise<EncryptionCapabilities>;
  getAdapter(): AdapterType;
}

Adapter Comparison

| Feature | PGP | NaCl | Node Crypto | |---------|-----|------|-------------| | Text Encryption | ✅ | ✅ | ✅ | | File Encryption | ✅ | ✅ | ✅ | | Email Encryption | ✅ | ❌ | ❌ | | Digital Signatures | ✅ | ✅ | ✅ | | Multiple Recipients | ✅ | ❌ | ❌ | | Symmetric | ❌ | ✅ | ✅ | | Asymmetric | ✅ | ✅ | ✅ | | Speed | Medium | Fast | Fast | | Key Size | Large | Small | Medium | | Best For | Email, compatibility | Performance, modern apps | Standard algorithms, built-in |

When to Use Each Adapter

PGP/OpenPGP - Best for:

  • Email encryption (PGP/MIME standard)
  • Multi-recipient scenarios
  • Compatibility with existing PGP infrastructure
  • Long-term archival

NaCl/libsodium - Best for:

  • High-performance applications
  • Modern cryptography
  • File encryption
  • API token encryption
  • Real-time data encryption

Node.js Crypto - Best for:

  • Standard algorithms (AES, RSA)
  • No external dependencies needed
  • Password-based encryption (PBKDF2)
  • Enterprise requirements (FIPS compliance)

Security Considerations

Key Storage

❌ DO NOT:

  • Store private keys in plain text
  • Commit keys to version control
  • Log keys or passphrases
  • Transmit keys over insecure channels

✅ DO:

  • Use environment variables for keys
  • Encrypt private keys with strong passphrases
  • Use hardware security modules (HSMs) for production
  • Implement key rotation policies
  • Use key derivation for password-based encryption

Best Practices

  1. Key Length:

    • RSA: Minimum 2048 bits (4096 recommended)
    • AES: 256 bits
    • ECC: curve25519 or P-384
  2. Algorithms:

    • ✅ Prefer: AES-256-GCM, RSA-OAEP, ECDH, NaCl
    • ❌ Avoid: DES, 3DES, MD5, SHA1
  3. Key Derivation:

    • PBKDF2: Minimum 100,000 iterations
    • Use unique salts per encryption
    • Consider Argon2 for new applications
  4. Encrypted Data Integrity:

    • Use authenticated encryption (GCM, Poly1305)
    • Always verify signatures before trusting data
    • Implement replay protection

Testing

Run the test suite:

npm test

Run tests for a specific adapter:

npm test -- test/unit/pgp.test.ts
npm test -- test/unit/nacl.test.ts
npm test -- test/unit/node.test.ts

Run file operations tests:

npm test -- test/unit/file-operations.test.ts

Performance Benchmarks

Approximate performance for 100KB data:

| Adapter | Encryption | Decryption | Key Generation | |---------|------------|------------|----------------| | PGP (RSA 4096) | ~200ms | ~100ms | ~3000ms | | NaCl (secretbox) | ~2ms | ~2ms | ~1ms | | AES-256-GCM | ~5ms | ~5ms | N/A | | RSA-OAEP 2048 | ~50ms | ~100ms | ~500ms |

Benchmarks run on M1 MacBook Pro. Your results may vary.

Documentation

  • AGENT.md - Comprehensive developer guide with detailed API reference, architecture, and implementation phases
  • API Types - TypeScript type definitions
  • Error Handling - Custom error classes

Examples

See the test directory for comprehensive examples:

Related Packages

Contributing

Contributions are welcome! Please see the root CONTRIBUTING.md for guidelines.

Development

# Install dependencies
pnpm install

# Run tests
npm test

# Run tests in watch mode
npm test -- --watch

# Build package
npm run build

# Lint and format
npm run lint
npm run format

License

MIT License - see LICENSE for details.

Support


Built with ❤️ by HappyVertical