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

safedrop-cli

v1.0.1

Published

Zero-knowledge, end-to-end encrypted file transfer from your terminal. Fully compatible with the SafeDrop web app.

Readme

safedrop-cli

Zero-knowledge, end-to-end encrypted file transfer from your terminal — fully compatible with the SafeDrop web app.

Files are encrypted on your machine before upload and decrypted on the receiver's machine after download. The SafeDrop server only ever sees ciphertext: it never receives your plaintext files, your real filenames, or your encryption keys.

A file sent from the CLI can be received in the browser, and a file sent from the browser can be received by the CLI — they use the identical encryption and code format.


Install

npm install -g safedrop-cli

Or run without installing:

npx safedrop-cli send ./report.pdf

Requires Node.js 18+ (uses the built-in fetch and crypto). The package has zero runtime dependencies, so it is small and easy to audit.


Quick start

Send a file

safedrop send ./report.pdf

The CLI encrypts the file locally, uploads the ciphertext, and prints a share code plus a share link. Give that code to your receiver. Then the receiver runs receive, reads you back a short handshake code, you paste it in, and the transfer is authorized.

Receive a file

safedrop receive eyJ1cGxvYWRDb2RlIjoi...

The CLI parses the code, shows you a handshake code to read to the sender, waits for them to authorize, then downloads and decrypts the file to your current directory.


Commands

safedrop send <file> [options]
safedrop receive <code-or-link> [options]

send options

| Option | Description | |---|---| | --ttl <minutes> | How long the transfer stays available before it expires. Default 15, max 1440 (24h). | | --secure | Enable full-security mode: both sides compare an out-of-band 3-word safety code to detect interception. | | --api <base-url> | Advanced: override the SafeDrop API URL. Defaults to https://safedrop.ma/api. |

receive options

| Option | Description | |---|---| | --output, -o <path> | Where to save the file. A directory (saves under the sender's filename) or a full file path. | | --api <base-url> | Advanced: override the SafeDrop API URL. Defaults to https://safedrop.ma/api. |

Examples

# Send with a 1-hour expiry and full-security verification
safedrop send ./contract.pdf --ttl 60 --secure

# Receive from a full browser link into your Downloads folder
safedrop receive "https://safedrop.ma/#code=eyJ1cGxv..." -o ~/Downloads/

# Receive and save under a specific name
safedrop receive eyJ1cGxv... -o ./received-contract.pdf

See examples/transcript-sender.txt and examples/transcript-receiver.txt for full end-to-end terminal walkthroughs.


How a transfer works

SENDER                          SAFEDROP SERVER                    RECEIVER
------                          ---------------                    --------
encrypt file + name locally
generate AES-256 key
   │ POST /initiate-upload ───────────▶ uploadCode, presigned URL,
   │                                    senderToken
   │ PUT ciphertext ──────────────────▶ (stores ciphertext only)
   │ POST /upload/:code/finalize ─────▶ (stores encrypted filename)
print share code  ◀────────────────────────────────────────────  paste code
                                                                   POST /handshake/initiate
                                    handshakeCode ◀──────────────  (gets handshake code)
read handshake code  ◀──────────────────────────────────────────  read it aloud
   │ POST /handshake/authorize ───────▶ issues download token
                                                  poll /handshake/token/:code ◀──
                                    downloadToken ─────────────────────────────▶
                                                  GET /upload/:code ◀───────────
                                    ciphertext ────────────────────────────────▶
                                    (server deletes its copy)      decrypt locally,
                                                                   save to disk

The key never leaves the client. The server stores only the encrypted bytes and the encrypted filename, and deletes both the moment the download completes.


Using it as a library

The encryption and code helpers are exported so you can build your own tools:

import {
  encryptBuffer, decryptBuffer,
  encodeCombinedCode, decodeCombinedCode,
  SafeDropApi,
} from 'safedrop-cli';

These are the same building blocks the CLI uses. See API.md for the HTTP contract and SECURITY.md for the threat model.


Security at a glance

  • AES-256-GCM authenticated encryption, done entirely client-side.
  • The server is zero-knowledge: no keys, no plaintext, no real filenames.
  • Share codes/links carry the key in the URL fragment (#code=...), which browsers never send to servers.
  • The CLI never logs file contents or keys; the share code is the only secret it prints, and only because sharing it is the entire purpose.
  • Downloaded filenames are sanitized — path traversal is refused and local files are never overwritten without confirmation.

Full details in SECURITY.md.


Development

npm test        # runs the cross-compatibility, code-parsing, and path tests

The crypto tests encrypt with the CLI and decrypt using the actual Web Crypto API (and vice versa) to guarantee browser ⇄ CLI compatibility.

License

MIT