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

daku

v0.1.0

Published

Leave no trace. Just authenticate.

Readme

DAKU

Anonymous authentication & encryption. Zero personal data. One library.

DAKU (Punjabi for "bandits") is a minimal cryptographic toolkit for building passwordless, privacy-first applications. No emails, no passwords, no databases of credentials to breach.

npm install daku

Why DAKU?

| Traditional Auth | DAKU | |------------------|------| | Store emails & passwords | Just verify signatures | | Hash passwords, manage resets | No passwords exist | | GDPR compliance headaches | No PII collected | | Database = honeypot for hackers | Nothing sensitive to steal | | OAuth complexity | 3 functions to authenticate |

import { generateKeyPair, createAuth, verifyAuth } from "daku";

// User creates identity (client-side, once)
const { privateKey, publicKey } = generateKeyPair();

// User logs in (client-side)
const token = await createAuth(privateKey);

// Server verifies (server-side)
const userId = await verifyAuth(token);  // Returns publicKey or null

That's it. No signup forms, no email verification, no password resets.


What DAKU Offers

🔑 Identity

generateKeyPair()              // Create new keypair identity
getPublicKey(privateKey)       // Derive public key from private
getUsername(publicKey)         // Human-readable name like "oceanrunning4523"

🎫 Authentication

createAuth(privateKey, pow?)   // Create login token (with spam protection)
verifyAuth(token, pow?)        // Verify token, returns publicKey or null

✍️ Signatures

sign(message, privateKey, pow?)      // Sign any data
verify(message, sig, publicKey, pow?)  // Verify signature
sha256(message)                      // SHA-256 hash

🔐 E2E Encryption

deriveSharedSecret(myPrivate, theirPublic)  // ECDH key agreement
encrypt(plaintext, key)                      // AES-256-GCM encrypt
decrypt(ciphertext, key)                     // AES-256-GCM decrypt

20+ Use Cases

| # | Use Case | |---|----------| | 1 | Anonymous chat apps — Users communicate without revealing identity or phone numbers | | 2 | Passwordless API authentication — Clients sign requests instead of using API keys | | 3 | End-to-end encrypted messaging — Private conversations only sender and receiver can read | | 4 | Anonymous feedback systems — Collect honest feedback without identifying who submitted it | | 5 | Whistleblower platforms — Secure, anonymous submission of sensitive information to journalists | | 6 | Decentralized identity — Users own their identity, no central authority controls access | | 7 | IoT device authentication — Devices authenticate without passwords or certificate authorities | | 8 | Wallet-based login — Same keys work with Bitcoin/Ethereum ecosystems (secp256k1) | | 9 | Document signing — Cryptographically sign contracts, agreements, or any digital document | | 10 | Anonymous voting systems — Verify votes are legitimate without revealing who voted | | 11 | Encrypted file sharing — Share files that only intended recipients can decrypt | | 12 | Private note-taking apps — Notes encrypted locally, unreadable even if server breached | | 13 | Spam-resistant forms — Proof-of-work prevents bots from mass-submitting without CAPTCHAs | | 14 | Multiplayer game authentication — Players authenticate without creating accounts or emails | | 15 | Anonymous support tickets — Users get help without revealing personal information | | 16 | Secure configuration sharing — Share secrets between team members with E2E encryption | | 17 | Timestamped proof of existence — Sign documents to prove they existed at specific time | | 18 | Private health apps — Health data stays encrypted, only user can access it | | 19 | Anonymous marketplace — Buy/sell without linking transactions to real identity | | 20 | Encrypted backups — Backup data that only you can restore, even on untrusted storage | | 21 | CLI tool authentication — Command-line tools authenticate without browser OAuth flows | | 22 | Peer-to-peer apps — Direct encrypted communication between users without servers | | 23 | Private analytics — Collect anonymous usage data without tracking individuals | | 24 | Secure team collaboration — Group encryption for team channels and shared documents |


How It Works

Authentication Flow

┌─────────────────────────────────────────────────────────────┐
│ CLIENT                                                      │
│                                                             │
│  1. First visit: generateKeyPair() → save privateKey        │
│  2. Login: createAuth(privateKey) → token                   │
│  3. Send token to server                                    │
└─────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│ SERVER                                                      │
│                                                             │
│  1. verifyAuth(token) → publicKey (user ID)                 │
│  2. publicKey is the unique, permanent user identifier      │
│  3. No passwords, no emails, no database of credentials     │
└─────────────────────────────────────────────────────────────┘

E2E Encryption Flow

Alice                                          Bob
  │                                             │
  │  1. deriveSharedSecret(alice.priv, bob.pub) │
  │     ═══════════════════════════════════     │
  │         (Both derive SAME secret)           │
  │     ═══════════════════════════════════     │
  │  2. deriveSharedSecret(bob.priv, alice.pub) │
  │                                             │
  │  3. encrypt("Hello", secret) ──────────────►│
  │                              ◄──────────────│ 4. decrypt(cipher, secret)
  │                                             │
  └─────────────────────────────────────────────┘
        Only Alice & Bob can read messages

Group Encryption

import { deriveSharedSecret, encrypt, decrypt } from "daku";
import crypto from "node:crypto";

// Admin creates group key (just random 32 bytes)
const groupKey = crypto.randomBytes(32).toString("hex");

// Distribute to each member securely
for (const member of members) {
  const secret = deriveSharedSecret(admin.privateKey, member.publicKey);
  const encryptedKey = await encrypt(groupKey, secret);
  // Send encryptedKey to member
}

// Member decrypts their copy
const memberSecret = deriveSharedSecret(member.privateKey, admin.publicKey);
const groupKey = await decrypt(encryptedKey, memberSecret);

// Everyone encrypts/decrypts with the shared group key
const message = await encrypt("Hello group!", groupKey);

Security

| Feature | Implementation | |---------|----------------| | Signatures | secp256k1 ECDSA (same as Bitcoin/Ethereum) | | Encryption | AES-256-GCM with random 96-bit IV | | Key Exchange | ECDH (Elliptic Curve Diffie-Hellman) | | Hashing | SHA-256 | | Spam Protection | Proof-of-work (configurable difficulty) | | Token Expiry | Auth tokens valid for 1 minute only |

What DAKU Protects Against

  • ✅ Password breaches (no passwords exist)
  • ✅ Credential stuffing (nothing to stuff)
  • ✅ Phishing (no credentials to phish)
  • ✅ Database leaks (no PII stored)
  • ✅ Replay attacks (1-minute token expiry)
  • ✅ Spam/bots (proof-of-work)
  • ✅ Man-in-the-middle (E2E encryption)

User Responsibilities

  • 🔑 Users must securely store their private key
  • 🔑 Lost private key = lost identity (no recovery)
  • 🔑 Compromised private key = compromised identity

Examples

Express.js Middleware

import { verifyAuth, getUsername } from "daku";

async function authMiddleware(req, res, next) {
  const token = req.headers.authorization?.replace("Bearer ", "");
  
  const publicKey = await verifyAuth(token);
  if (!publicKey) {
    return res.status(401).json({ error: "Unauthorized" });
  }
  
  req.userId = publicKey;
  req.username = getUsername(publicKey);
  next();
}

React Login

import { generateKeyPair, createAuth } from "daku";

function useAuth() {
  const login = async () => {
    let privateKey = localStorage.getItem("privateKey");
    
    if (!privateKey) {
      const keys = generateKeyPair();
      privateKey = keys.privateKey;
      localStorage.setItem("privateKey", privateKey);
    }
    
    const token = await createAuth(privateKey);
    return fetch("/api/login", {
      headers: { Authorization: `Bearer ${token}` }
    });
  };
  
  return { login };
}

Encrypted Chat

import { deriveSharedSecret, encrypt, decrypt } from "daku";

// Both users derive the same shared secret
const secret = deriveSharedSecret(myPrivateKey, theirPublicKey);

// Send encrypted message
const encrypted = await encrypt("Hello!", secret);
ws.send(encrypted);

// Receive and decrypt
ws.onmessage = async (e) => {
  const message = await decrypt(e.data, secret);
  console.log(message);
};

API Reference

generateKeyPair()

Creates a new secp256k1 keypair.

const { privateKey, publicKey } = generateKeyPair();
// privateKey: 64-char hex (keep secret!)
// publicKey: 66-char hex (share freely)

getPublicKey(privateKey)

Derives public key from private key.

const publicKey = getPublicKey(privateKey);

getUsername(publicKey)

Generates a deterministic human-readable username.

const name = getUsername(publicKey); // "oceanrunning4523"

createAuth(privateKey, pow?)

Creates a signed authentication token. Default POW difficulty is 2.

const token = await createAuth(privateKey);
const token = await createAuth(privateKey, 3); // Higher difficulty

verifyAuth(token, pow?)

Verifies an auth token. Returns publicKey on success, null on failure.

const publicKey = await verifyAuth(token);
if (publicKey) {
  // Authenticated! publicKey is the user ID
}

sign(message, privateKey, pow?)

Signs a message with proof-of-work.

const sig = await sign("Hello", privateKey);
// { signature: "...", pow: 123 }

verify(message, signatureData, publicKey, pow?)

Verifies a signature.

const isValid = await verify("Hello", sig, publicKey);

sha256(message)

SHA-256 hash.

const hash = await sha256("Hello"); // Uint8Array(32)

deriveSharedSecret(myPrivateKey, theirPublicKey)

ECDH key agreement. Both parties derive the same secret.

const secret = deriveSharedSecret(alice.privateKey, bob.publicKey);
// Same as: deriveSharedSecret(bob.privateKey, alice.publicKey)

encrypt(plaintext, key)

AES-256-GCM encryption.

const ciphertext = await encrypt("Secret message", sharedSecret);

decrypt(ciphertext, key)

AES-256-GCM decryption. Returns null on failure.

const plaintext = await decrypt(ciphertext, sharedSecret);

Comparison

| Feature | DAKU | Passport.js | Auth0 | Firebase Auth | |---------|------|-------------|-------|---------------| | No passwords | ✅ | ❌ | ❌ | ❌ | | No email required | ✅ | ❌ | ❌ | ❌ | | No database needed | ✅ | ❌ | ❌ | ❌ | | E2E encryption | ✅ | ❌ | ❌ | ❌ | | Self-hosted | ✅ | ✅ | ❌ | ❌ | | Zero dependencies* | ✅ | ❌ | ❌ | ❌ | | Works offline | ✅ | ❌ | ❌ | ❌ | | Bundle size | ~50KB | ~200KB | SDK required | SDK required |

*Only 2 peer dependencies: @noble/secp256k1 and @noble/hashes


Installation

npm install daku

Requirements: Node.js 16+ or modern browser


License

ISC © besoeasy