Share secrets, not risks.
Client-side encryption tool that converts text and files into password-protected .zefer files using AES-256-GCM. 100% browser-based — no servers, no traces, no cookies.
Live Demo · CLI (zefer-cli) · Report Bug · Request Feature · Security Report · Documentation
- About
- CLI
- Features
- Architecture
- Binary File Format
- Quick Start
- Tech Stack
- Project Structure
- Routes
- URL Parameters
- Testing
- Security Model
- Legal Compliance
- Deployment
- AI Integration
- Contributing
- Documentation
- Author
- Support
- License
Zefer encrypts your secrets into password-protected .zefer files using AES-256-GCM with PBKDF2-SHA256 key derivation, entirely in your browser. Nothing ever leaves your device unencrypted.
- Zero-knowledge — the server never sees plaintext, passphrases, or encryption keys
- No cookies, no analytics, no trackers — zero data collection
- Open source — MIT license, fully auditable
- Standards-based — Web Crypto API, CompressionStream API, no third-party crypto dependencies
Zefer has an official command-line companion — zefer-cli — for scripting, automation, and terminal workflows. .zefer files are fully cross-compatible between the web app and the CLI.
Via npm (recommended):
npm install -g zefer-cli
zefer encrypt report.pdf -p mypassword
zefer decrypt report.pdf.zefer -p mypassword
zefer keygen --mode secure --length 64
zefer info secret.zeferStandalone binary (no Node.js required): download for Linux x64 · Linux ARM64 · macOS Intel · macOS Apple Silicon · Windows x64
|
Encryption
|
Security Layers
|
|
Developer Experience
|
Accessibility & i18n
|
Browser (client-side only)
│
├── Text / File input (click or drag-and-drop)
├── Passphrase + options
├── PBKDF2 key derivation (Web Crypto API)
├── AES-256-GCM chunked encryption (Web Crypto API)
├── Optional: Gzip/Deflate compression (CompressionStream API)
├── Optional: Reveal key (second encrypted block)
└── .zefer file download (ZEFB3 or ZEFR3 binary format)
No server involved
For detailed data flow diagrams, component tree, and theming system, see docs/ARCHITECTURE.md.
ZEFB3 (5 bytes magic)
header_length (4 bytes, big-endian)
header_json ← public header (minimal)
salt (32 bytes) + iv (12 bytes)
encrypted_chunks ← 16MB per chunk, unique IV per chunk
ZEFR3 (5 bytes magic)
header_length (4 bytes, big-endian)
header_json ← public header (minimal)
main_block_size (4 bytes)
main_salt + main_iv + main_chunks ← encrypted with main passphrase
reveal_salt + reveal_iv + reveal_chunks ← encrypted with reveal key
Public header (visible without decryption): iterations, compression, hint, note, mode
Encrypted payload (invisible without the key): content, file metadata, expiration, secret question, IP list, max attempts
Legacy text formats (ZEFER3, ZEFER2) are supported for backward-compatible decryption only.
- Node.js 20+
- npm 10+
git clone https://github.com/carrilloapps/zefer.git
cd zefer
npm install
npm run devOpen http://localhost:3000.
npm test # 125 tests
npx tsc --noEmit # Type check
npm run build # Production build| Layer | Technology |
|---|---|
| Framework | Next.js 16.2.3 (React 19) |
| Language | TypeScript 6 |
| Styling | Tailwind CSS v4 |
| Encryption | Web Crypto API (AES-256-GCM) |
| Key Derivation | PBKDF2-SHA256 (300k-1M iterations) |
| Compression | CompressionStream API (Gzip/Deflate) |
| Icons | Lucide React |
| Notifications | Sonner |
| Testing | Vitest + @vitest/coverage-v8 |
| Hosting | Vercel / Any static host |
app/
api/
author/route.ts # GitHub profile API (cached 1h)
components/ # 24 client components
EncryptForm.tsx # Encrypt text/files
DecryptForm.tsx # Decrypt .zefer files
HomeContent.tsx # Home page with tabs
KeyGenerator.tsx # Secure key generator popover
CryptoProgress.tsx # Encryption/decryption progress bar
... # 19 more components
lib/
crypto.ts # AES-256-GCM + PBKDF2 + benchmarking
zefer.ts # .zefer format encode/decode (ZEFB3/ZEFR3)
chunked-crypto.ts # Chunked encryption (16MB per chunk)
compression.ts # Gzip/Deflate via CompressionStream
device.ts # RAM/CPU/GPU detection + file limits
i18n.ts # Translations (es/en/pt, ~415 keys)
ip.ts # IP detection and restriction
notify.ts # Toast notification helpers
preferences.ts # Persisted user preferences
progress.ts # Encryption progress tracking
__tests__/ # 125 Vitest tests (7 files)
globals.css # Design system (liquid glass, theming)
layout.tsx # Root layout + providers
page.tsx # Home page
docs/ # Architecture, Security, Deployment, Contributing
public/
llms.txt # LLM context file (llmstxt.org standard)
| Route | Type | Indexed | Description |
|---|---|---|---|
/ |
Static | Yes | Home — encrypt/decrypt forms |
/how |
Static | Yes | How it works — 7 steps + features + specs |
/project |
Static | Yes | Project info, tech stack, creator, donate |
/device |
Static | Yes | Device detection details + optimization guide |
/install |
Static | Yes | Usage guide, self-hosting, PWA, native apps |
/install/guide |
Static | Yes | Step-by-step usage guide for AI assistants |
/privacy |
Static | No | Privacy policy + GDPR/CCPA/LGPD compliance |
/terms |
Static | No | Terms, conditions, MIT license, legal compliance |
/api/author |
Dynamic | — | GitHub profile data (cached 1h) |
/llms.txt |
Static | Yes | LLM context file |
Pre-configure forms via URL for workflow automation. Every parameter has a long name and short alias. Sensitive params are auto-cleared from the URL after reading.
| Long | Short | Type | Values |
|---|---|---|---|
passphrase |
p |
string | min 6 chars |
passphrase2 |
p2 |
string | min 6 chars (enables dual key) |
dual |
d |
flag | 1 / true |
reveal |
r |
string | min 6 chars |
mode |
m |
enum | text / file |
ttl |
— | number | 0=never, 30, 60, 1440, 10080, 20160 (minutes) |
security |
s |
enum | standard / high / maximum |
iterations |
i |
number | 300000-1000000 |
compression |
c |
enum | none / gzip / deflate |
hint |
h |
string | any |
note |
n |
string | any |
question |
q |
string | any |
answer |
a |
string | any |
attempts |
att |
number | 0, 3, 5, 10 |
ips |
— | string | comma-separated IPv4/IPv6 |
| Long | Short | Type |
|---|---|---|
passphrase |
p |
string |
passphrase2 |
p2 |
string (enables dual key) |
dual |
d |
flag |
answer |
a |
string |
/?t=decrypt&p=mySecret123
/?t=encrypt&m=file&ttl=30&c=gzip&s=high
/?t=encrypt&p=key1&p2=key2&q=Color%3F&a=blue&ips=10.0.0.1,192.168.1.5&s=maximumnpm test # Run 125 tests
npm run test:watch # Watch mode| Metric | Value |
|---|---|
| Test files | 7 |
| Total tests | 125 |
| Statements | 100% |
| Functions | 100% |
| Lines | 100% |
| Branches | 99.47% |
- All encryption/decryption happens in the browser via Web Crypto API
- The server never sees plaintext, passphrases, or encryption keys
- The
.zeferfile header contains only minimal technical data - All security metadata (expiration, IPs, question) is inside the encrypted payload
- An attacker with the file cannot determine what security features are enabled
- Each file has unique encryption (random salt + IV per block)
- Reveal key is independently encrypted with its own salt, IV, and derived key
| Primitive | Algorithm | Parameters |
|---|---|---|
| Symmetric encryption | AES-256-GCM | 256-bit key, 96-bit IV, 128-bit auth tag |
| Key derivation | PBKDF2-SHA256 | 300k/600k/1M iterations, 256-bit salt |
| Answer hashing | PBKDF2-SHA256 | 100,000 iterations |
| Random generation | crypto.getRandomValues |
OS-level CSPRNG |
For the full threat model, known limitations, and security guarantees, see docs/SECURITY.md.
| Regulation | Status |
|---|---|
| GDPR (EU) | Compliant — no personal data collected |
| CCPA (California) | Compliant — no personal information sold or shared |
| LGPD (Brazil) | Compliant — Art. 5, 18 |
| Law 1581 (Colombia) | Compliant — Art. 4, 9 |
| ePrivacy Directive | Compliant — no cookies, trackers, or analytics |
| Method | Command | Notes |
|---|---|---|
| Vercel | Push to GitHub + Import in Vercel | Recommended, zero-config |
| Docker | docker build -t zefer . && docker run -p 3000:3000 zefer |
Production-ready Dockerfile in docs/DEPLOYMENT.md |
| Static export | npm run build with output: "export" |
Disables /api/author route |
| Self-hosted | npm run build && npm start |
Requires Node.js 20+, HTTPS |
HTTPS is required — Web Crypto API is only available in secure contexts. See the full Deployment Guide.
Zefer publishes /llms.txt following the llmstxt.org standard. Any AI tool can use it as context:
| Tool | Usage |
|---|---|
| Claude Code | Reads CLAUDE.md and AGENTS.md automatically when cloned |
| GitHub Copilot | @workspace /explain #file:llms.txt |
| Cursor / Windsurf / Augment | Add llms.txt as context file |
| Any LLM | Pass https://zefer.carrillo.app/llms.txt as context URL |
Contributions are welcome! Please read the Contributing Guide and Code of Conduct before submitting a pull request.
- Fork the repository
- Create a feature branch (
git checkout -b feature/your-feature) - Run tests (
npm test) and verify types (npx tsc --noEmit) - Submit a pull request
| Document | Description |
|---|---|
| Architecture | Data flow, binary format, component tree, theming |
| Security | Threat model, cryptographic primitives, guarantees, limitations |
| Deployment | Vercel, Docker, static export, self-hosting |
| Contributing | Setup, conventions, PR workflow |
| Security Policy | Vulnerability reporting, response timeline, scope |
| Code of Conduct | Contributor Covenant community standards |
| Changelog | Version history and release notes |
Jose Carrillo — Senior Fullstack Developer & Tech Lead
10+ years building scalable, efficient, and secure software. Based in Colombia.
If you find Zefer useful, consider supporting the project:
MIT © 2026 Jose Carrillo