Documentation
notepadable
A minimalist text editor that encodes your entire document into the URL. No server, no database, no accounts.
What it's good for
notepadable is built around one idea: the URL is the document. There is no backend storing your text. Everything lives in the hash fragment at the end of the URL.
Write something, copy the URL, send it. The recipient sees exactly what you wrote — no accounts, no uploads, no expiry date.
Save a notepadable URL to your bookmarks and the text travels with it. The note is as durable as the bookmark.
Snippets, draft messages, quick reference text. Nothing lingers on a server because nothing ever reaches one.
Use the /raw API to pull the plain text of any notepadable link directly into a shell script or CI pipeline.
How it works
When you type in the editor, your text is compressed and written to the URL hash. The compression runs entirely in the browser — no round-trip to a server at any point.
Compression pipeline
Text is compressed in two stages before it reaches the URL:
- Dictionary encoding. A built-in dictionary of 4,096 common English words maps each matching word to a 12-bit index. Typical English prose compresses significantly in this step alone. Title-cased variants get a dedicated token so they round-trip without loss.
-
LZ compression. The dictionary-encoded binary payload is then run through lz-string's
compressToEncodedURIComponent, which produces a compact, URL-safe string with no characters that need percent-encoding.
The final string is placed directly after # in the URL.
Encoding walkthrough
Take the sample sentence The cat is happy. The encoder first splits it into words and separators, then turns each token into either a dictionary reference or a literal byte sequence before packing the bits into bytes.
The cat is happy
The cat is happy
Words become dictionary indexes. Spaces stay as 1-byte literals.
80 00 04 04 80 DB F0 12 00 03 C0 48 09 FE
01 00 + dict bytes
IAAAASAglg2wDwJBAYAAMAkCQA-oA
| Token | Encoding | Bits written |
|---|---|---|
The |
Title-case dictionary word, using the index for the (0) |
1 + 00000000 + 000000000000 |
|
Literal space, UTF-8 length 1, byte 0x20 |
1 + 00000001 + 00100000 |
cat |
Lowercase dictionary word, index 1759 |
0 + 011011011111 |
|
Literal space, UTF-8 length 1, byte 0x20 |
1 + 00000001 + 00100000 |
is |
Lowercase dictionary word, index 7 |
0 + 000000000111 |
|
Literal space, UTF-8 length 1, byte 0x20 |
1 + 00000001 + 00100000 |
happy |
Lowercase dictionary word, index 1279 |
0 + 010011111111 |
Those token writes add up to 111 meaningful bits, which the bit writer pads to 112 so it can flush exactly 14 bytes:
80 00 04 04 80 DB F0 12 00 03 C0 48 09 FE
The plain-text payload adds a version byte and a flags byte in front of that stream:
[version=01] [flags=00] [dict=80 00 04 04 80 DB F0 12 00 03 C0 48 09 FE]
toBinaryString() then turns those 16 payload bytes into a 16-character binary string, and compressToEncodedURIComponent() converts that into the final URL-safe fragment:
IAAAASAglg2wDwJBAYAAMAkCQA-oA
URL storage
The compressed text lives in the URL hash fragment — the part after #. Hash fragments are never sent to the server by the browser, so your text stays entirely on the client. notepadable's servers never see it.
As a fallback, the last hash is also cached in localStorage so the editor restores your content even if you navigate to /app without a hash.
Limits
There is no hard server-side limit on URL length, but practical limits exist:
- Most browsers handle URLs up to ~64KB comfortably.
- Many link-sharing platforms (Slack, Twitter, etc.) truncate or refuse very long URLs. A practical safe limit is roughly 10–14 KB of source text after compression.
- The
localStoragefallback has the same constraint.
The /raw API
Any notepadable link can be turned into a plain-text endpoint. Take the hash that normally follows /app# and pass it as a path segment to /raw/. The server decompresses it and responds with Content-Type: text/plain.
This is a genuine server-side endpoint — curl-able, script-friendly, and returns raw text with no HTML wrapper.
Plain text
For a link like notepadable.com/app#IAAAgQi..., the raw equivalent is:
curl notepadable.com/raw/IAAAgQi...
Your plain text content here.
Encrypted documents
If the document is password-protected, pass the password as a ?p= query parameter:
curl "notepadable.com/raw/IAAAgQi...?p=yourpassword"
If you omit ?p= on an encrypted document, the API returns a 401 with a message telling you to supply the password. A wrong password also returns 401.
Encryption
Documents can be password-protected from the editor toolbar. The encryption happens entirely in the browser before the text touches the URL.
- Algorithm: AES-256-GCM via the Web Crypto API.
- Key derivation: PBKDF2 with 100,000 iterations and SHA-256, salted with 16 random bytes per encryption.
- IV: 12 random bytes generated fresh for every encryption.
The salt and IV are stored alongside the ciphertext in the URL hash. The password is never stored or transmitted — it exists only in your browser's memory while the tab is open.
Markdown & Mermaid
The editor includes a preview mode that renders your text as Markdown using marked. Toggle preview from the toolbar or with the keyboard shortcut.
Mermaid diagrams are supported in preview mode. Wrap your diagram in a fenced code block tagged mermaid:
```mermaid
graph TD
A[Start] --> B{Decision}
B -->|Yes| C[Do thing]
B -->|No| D[Skip]
```
Mermaid is loaded on demand from a CDN when the preview is first opened, so it does not add to the initial page weight.