How lwid works
An encrypted, zero-knowledge platform for sharing small web apps.
All your data is encrypted and decrypted directly in your browser before anything leaves your machine. The server never sees your files, your keys, or your filenames — only encrypted gibberish blobs.
Security model
End-to-end encryption
Every file is encrypted with AES-256-GCM in your browser before it leaves your machine. The server only ever receives and stores opaque ciphertext blobs.
Zero-knowledge server
The server never sees your content, your keys, or your filenames. It stores content-addressed blobs identified by their IPFS CIDv1 hash — nothing more.
Keys live in the URL fragment
The decryption key is encoded in the #fragment part of
the URL. Browsers never send the fragment to the server
— it stays entirely client-side.
Quotas
Limits per account tier. Sign in to unlock higher limits.
| Limit | Anonymous |
|---|---|
| Loading… | |
Usage
Web UI
- Go to lookwhatidid.xyz.
- Drop your project folder (must contain an
index.html). - Click Create & Share.
- You'll be redirected to your project's URL with both keys in the fragment.
- Share the view-only link (read key only) or the edit link (both keys).
CLI
Install the lwid CLI:
macOS / Linux:
Windows (PowerShell):
First push (new project)
This generates keys, creates the project, encrypts and uploads all files,
and prints the shareable URL. A .lwid.json config file is
saved in the directory.
.lwid.json to your
.gitignore immediately — it contains your encryption
and signing keys.
Update an existing project
lwid push
Reads config from .lwid.json in the current directory.
Pull a project
lwid pull --dir .
Project info
lwid info
Prints project ID, server URL, edit URL, and view-only URL.
AI agent integration
Any coding agent that supports skill files can publish to lwid automatically. Point your agent at the skill URL:
https://lookwhatidid.xyz/SKILL.md
The skill instructs the agent to install the CLI, run lwid push,
and return the shareable URL. No manual steps required.
Architecture
You (browser / CLI) Server
┌──────────────────────┐ ┌──────────────────┐
│ │ │ │
│ 1. Generate keys │ │ Stores only: │
│ - AES-256-GCM │ encrypted │ - CID → blob │
│ - Ed25519 seed │──── blobs ────▶│ - project → CID │
│ │ │ │
│ 2. Encrypt files │ │ Never sees: │
│ 3. Compute CID │ │ - plaintext │
│ 4. Upload blobs │ │ - keys │
│ 5. Build manifest │ │ - filenames │
│ 6. Sign & upload │ │ │
│ │ └──────────────────┘
└──────────────────────┘
URL: /p/{project-id-OA4cCJ3}#{read-key}:{write-key}
└─── sent to server ──┘└───── never sent ────┘
Encryption & keys
When you create a project, two keys are generated client-side:
- Read key (32 bytes) — AES-256-GCM symmetric key used to encrypt and decrypt all file content.
- Write key (32 bytes) — Ed25519 seed used to derive a signing keypair. The server stores only the public key and verifies signatures on manifest updates.
Both keys are encoded as base64url (no padding) and
placed in the URL fragment: #readkey:writekey. A view-only
URL omits the write key: #readkey.
Content-addressed storage
Each encrypted blob is hashed with SHA2-256 and
stored under its IPFS CIDv1 (multicodec
raw, multibase base32lower). This means:
- Identical content is stored once (deduplication).
- Integrity is verifiable by recomputing the hash.
- The server cannot tamper with content without detection.
Manifests & versioning
A manifest is a JSON document listing all files in a version: path, CID, and size for each entry. The manifest itself is encrypted, uploaded as a blob, and its CID becomes the project's root.
Each manifest points to its predecessor via a parent
CID, forming a linked version chain. Updating the root requires
a valid Ed25519 signature from the write key.
Service Worker sandbox
In the browser, files are decrypted in the main thread and passed to
a Service Worker via postMessage.
The SW intercepts fetch requests under /sandbox/
and serves the decrypted files from memory, so the project renders
in a sandboxed <iframe> without any plaintext
hitting the network.
URL scheme
| Type | Format | Who can… |
|---|---|---|
| View | /p/{project-id}#{read-key} |
Decrypt and view the project |
| Edit | /p/{project-id}#{read-key}:{write-key} |
View + push new versions |
Keys are base64url-encoded (no padding). The fragment
(#...) is never sent to the server by the browser.
Source code
lwid is open source. The Rust workspace has three crates:
| Crate | Purpose |
|---|---|
lwid-common | Shared types, AES-256-GCM crypto, Ed25519 auth, CID utilities, blob/project stores |
lwid-server | Axum HTTP server, API endpoints, static file serving |
lwid-cli | CLI binary — push, pull, info commands |