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

@djangocfg/crypto

v2.1.135

Published

Client-side AES-256-GCM decryption for Django-CFG encrypted API responses using Web Crypto API

Readme

@djangocfg/crypto

Client-side AES-256-GCM decryption for Django-CFG encrypted API responses using Web Crypto API.

Installation

pnpm add @djangocfg/crypto

Features

  • AES-256-GCM authenticated decryption
  • PBKDF2 key derivation (matches Django-CFG backend)
  • Zero dependencies (uses native Web Crypto API)
  • TypeScript support with full type inference
  • React hooks for declarative decryption
  • Per-user and per-session key isolation

Usage

Basic Usage

import { createDecryptionClient } from '@djangocfg/crypto';

// Create a decryption client
const crypto = await createDecryptionClient({
  secretKey: 'your-django-secret-key',
  userId: 123,  // optional, for per-user encryption
});

// Fetch encrypted data
const response = await fetch('/api/products/?encrypt=true');
const encryptedData = await response.json();

// Decrypt all encrypted fields
const data = await crypto.decryptObject(encryptedData);
console.log(data.price); // decrypted value

React Hooks

import { useDecrypt } from '@djangocfg/crypto/react';

function ProductPrice({ product }: { product: Product }) {
  const { data, isLoading, error } = useDecrypt(product, {
    secretKey: process.env.NEXT_PUBLIC_DECRYPT_KEY!,
    userId: user.id,
  });

  if (isLoading) return <Skeleton />;
  if (error) return <ErrorMessage error={error} />;

  return <span>${data.price}</span>;
}

Lazy Decryption

import { useLazyDecrypt } from '@djangocfg/crypto/react';

function LazyProduct({ product }: { product: Product }) {
  const { decrypt, data, isLoading } = useLazyDecrypt({
    secretKey: process.env.NEXT_PUBLIC_DECRYPT_KEY!,
  });

  return (
    <div>
      <button onClick={() => decrypt(product)}>
        Show Price
      </button>
      {isLoading && <Spinner />}
      {data && <span>{data.price}</span>}
    </div>
  );
}

API Reference

Core Functions

createDecryptionClient(config)

Creates a decryption client with pre-derived key.

const crypto = await createDecryptionClient({
  secretKey: string;      // Django SECRET_KEY
  userId?: string|number; // Optional user ID
  sessionId?: string;     // Optional session ID
  iterations?: number;    // PBKDF2 iterations (default: 100000)
  keyPrefix?: string;     // Key prefix (default: "djangocfg_encryption")
});

// Methods
await crypto.decryptField(encryptedField);  // Decrypt single field
await crypto.decryptObject(data);           // Decrypt all fields recursively
crypto.isEncryptedField(value);             // Type guard

decryptField(field, key)

Decrypt a single encrypted field.

decryptObject(data, key)

Recursively decrypt all encrypted fields in an object.

React Hooks

useDecrypt(data, config)

Decrypt data on mount.

useDecryptionClient(config)

Create a memoized decryption client.

useLazyDecrypt(config)

Decrypt data on demand with manual trigger.

useIsEncrypted(value)

Check if a value is encrypted.

Types

interface EncryptedField {
  encrypted: true;
  field?: string;
  algorithm: 'AES-256-GCM';
  iv: string;        // base64
  data: string;      // base64
  auth_tag: string;  // base64
}

interface DecryptionConfig {
  secretKey: string;
  userId?: string | number;
  sessionId?: string;
  iterations?: number;
  keyPrefix?: string;
}

Security Notes

  • Never expose your Django SECRET_KEY directly in frontend code
  • Use a dedicated decryption key or derive one securely
  • Consider per-user keys for sensitive data isolation
  • PBKDF2 iterations must match backend configuration

License

MIT