A file that saves itself.
From nothing to an HTML file on your own machine that keeps every edit. No account, no build step, nothing to configure. Four steps, about two minutes.
My notes
Type anything here.
Click and type, then just stop. Autosave is on, the same way it will be in your file. Refresh the page and your words are still here.
This copy saves into your browser's storage through the real save pipeline; a save normally writes to disk. The steps below give you the real thing: a file on disk that does it.
See the HTML a save writesclay.getHTML()
This demo sheet's slice of the exact string clay.getHTML() returns: the payload a save sends, after cleanup. Your edits are just markup now.
The complete file behind a page like that:
<!DOCTYPE html>
<html lang="en" autosave>
<head><meta charset="utf-8"><title>Notes</title></head>
<body>
<h1 editable>My notes</h1>
<div editable><p>Type anything here.</p></div>
<script src="https://clayjs.com/clay.js"></script>
</body>
</html>
2 · Save the file, rename it .htmlclay → double-click opens it, served
3 · Add one script tag → the page can save itself
4 ·
editable + autosave → what you type lands in the file
Step 1 · Get the app
A browser can't write to a file on your disk.
Something outside the browser sandbox has to hold the pen. HTML Clay is that something: a small desktop app whose whole job is to serve your file locally and write saves back into it. No account, and it only ever writes inside your home folder: the file you opened, or a folder you explicitly trust.
Free. macOS universal dmg, signed and notarized, about 8.6 MB · Windows 64-bit zip, signed, about 3.7 MB · Linux tar.gz, about 4.3 MB, x86_64 and ARM64. All downloads.
The mac installer's file name carries its version number, so on a Mac the button goes through htmlclay.com's always-current download list. No security-warning workarounds are needed on any platform; the builds are signed.
Step 2 · Make the file
Double-clicking an HTML file just views it.
Copy this and save it as notes.html, anywhere inside your home folder. (The app refuses to serve anything outside it, so keep it there.) Any HTML file you already have works exactly the same way.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>Notes</title></head>
<body>
<h1>My notes</h1>
<div><p>Type anything here.</p></div>
</body>
</html>
Now rename notes.html to notes.htmlclay and double-click it. HTML Clay serves it at http://127.0.0.1 and opens it in your default browser, as an ordinary tab. Right now it is just a page; the next two steps make it a document.
On a machine without the app, nothing is lost: it is still an ordinary HTML file. Rename it back to .html and any browser opens it. Nothing about the file depends on the app.
Step 3 · Add the script tag
The page doesn't know how to save itself yet.
<script src="https://clayjs.com/clay.js"></script>
Open notes.htmlclay in your text editor, add that line just before </body>, save, and refresh the tab. Nothing visible changes, but the wiring is now live: when HTML Clay serves the file it stamps a save token onto <html>, and clayjs reads that token, switches into edit mode on its own, and knows to POST the whole document back to the app. No config, no save code to write.
Step 4 · Turn on editing
Nothing on the page is editable yet.
Two attributes. editable on any element makes it rich text you can type into, with bold, lists, and links. autosave on <html> saves after your edits settle, debounced and throttled; ⌘S or Ctrl+S always works too.
<html lang="en" autosave>
<div editable><p>Type anything here.</p></div>
Add them, refresh the tab, and your file now matches the complete file at the top of this page.
Now prove it to yourself. Type into the page, stop for a moment, then open notes.htmlclay in your text editor. Your words are in the file. That file is the whole app.
While it works, clayjs keeps a savestatus attribute on <html> up to date (saving, saved, error, offline) and draws no interface of its own. Style it with a few lines of CSS, listen to the clay:save-* events (that is what this page's status chip does), or load a ready-made chip with clay.js?plugins=indicator. Details in the reference.
Three parts, one document
The file owns everything: the interface and the state are one HTML document. clayjs, inside the page, turns your edits into a clean serialized copy of that document. HTML Clay, outside the browser, is the only part that touches disk: it serves the file up and writes the saves back.
The save is one POST of the whole document, as plain text, to /_/save/<token> on the local app. What lands on disk is HTML you can read. The same one-route protocol runs hyperclay.com and about 20 lines of your own server.
clayjs is free to use in anything; the precise terms are its LICENSE. HTML Clay is source-available (not open source) under the First Million Stays Yours License: free to use for anything, and it only costs money if you sell or host a product built on it that makes more than $1M a year.
You have a file. Now make it an app.
The reference: API, attributes, events → /docs
Host it anywhere: the one-route endpoint spec → /docs#endpoint
Everything the app does: versions, live sync, the wire → htmlclay.com/features
Is it safe? The exact boundary → htmlclay.com/#safe
Honest questions, honest answers
Isn't this just contenteditable plus a POST?mostly, yes
Mostly, yes. contenteditable has been in browsers for twenty years, and the save is one POST of the whole document. The news is what is missing: no format of its own, no export step, no cloud in the loop. Double-click a file, edit it like a document, and the exact HTML you were looking at is written back to the same file, clean enough to read. clayjs earns its keep on the unglamorous parts, a clean serialize with the runtime junk stripped, autosave that settles instead of spamming, a warning before you close unsaved work, but the core is as simple as you suspect. That simplicity is the point.
A desktop app is a bigger ask than a script tag.it is
It is. But a web page cannot write to your disk; the sandbox is the one rule this idea cannot cross, so a native process has to do the writing. HTML Clay is deliberately small about it: 4 to 9 MB, signed, no account, and it only ever writes inside your home folder, into the file you opened or a folder you explicitly trust. It also brings more than the pen: every file it opens gets automatic version history, an edit from a text editor or an agent merges into the open page without a reload, and a local program can work on the file through the wire. The full list is at htmlclay.com/features. If you'd rather install nothing, hyperclay.com hosts the same files, saved to their disk instead of yours.
What actually gets sent when it saves?the whole file
The entire document, serialized as HTML and POSTed as plain text to the local app. There is no hidden project format and no sidecar files: what lands on disk is the same kind of HTML you would write by hand. clay.getHTML() returns the exact string, and the fold at the top of this page shows it live.
View source shows attributes I didn't write.two, one stays
When HTML Clay serves your file it puts two attributes on <html>: htmlclaytoken, a per-serve save credential, and htmlclayid, a durable identity for the file. clayjs adds savestatus while it works. Before anything is written to disk, htmlclaytoken and savestatus are stripped. htmlclayid is kept: it is how the app still recognizes the file after you rename or move it. So the browser shows three attributes you didn't write, and the file on disk gains exactly one.
Already have a static file?
The notes file above is only an example. The same four steps work on any HTML you own: a page you already have, or the personal software you have been meaning to build. Paste the prompt below at a coding agent (Claude, Cursor, Codex…), with your file if you have one, and it does steps 3 and 4 for you.
Type it and the prompt below asks the agent to build it first. Leave it empty if you're bringing a file you already have.
Make this static HTML file malleable with clayjs. Read https://clayjs.com/llms.txt before you start: it is the full clayjs reference, including every plugin and advanced module. Add <script src="https://clayjs.com/clay.js"></script> as the last element inside <body>. Add an autosave attribute to the <html> element. Add an editable attribute to each element a person should be able to edit as rich text (headings, paragraphs, note containers), and add a persist attribute to any form control whose value should survive saving. Do not write any save logic or add a save button: clayjs saves the whole document automatically, and the host (the HTML Clay desktop app for .htmlclay files, or hyperclay.com) writes it to disk. If part of the page is UI that should never be written to disk, mark it clay="no-save no-watch". Change nothing else.