- HTML Clay
- Guide
- Quick start
Quick start
Install HTML Clay, save a file that saves itself, change it in the browser, and learn the three attributes that did the work.
Your first self-saving file takes about five minutes: install the app, save one HTML file with a .htmlclay ending, and edit it in the browser. There is no save button and no account.
Install#
The download is free and there is no account. Choose your download.
The current published release is 1.7.0. The authoritative answer for what is current is the in-app update feed, which is a plain JSON file:
curl https://download.htmlclay.com/htmlclay-release-info.json
# {"latest":"1.7.0","url":"https://htmlclay.com/#downloads","date":"...","files":[...]}
Downloads, all from https://htmlclay.com#downloads:
| Platform | File |
|---|---|
| macOS, universal, signed and notarized | https://download.htmlclay.com/HTMLClay-1.7.0-universal.dmg |
| Windows x64, signed | https://download.htmlclay.com/htmlclay-windows-amd64.zip |
| Windows ARM64, signed | https://download.htmlclay.com/htmlclay-windows-arm64.zip |
| Linux x86_64 | https://download.htmlclay.com/htmlclay-linux-amd64.tar.gz |
| Linux ARM64 | https://download.htmlclay.com/htmlclay-linux-arm64.tar.gz |
| Checksums | https://download.htmlclay.com/SHA256SUMS |
Only the macOS dmg carries the version in its filename. The other four names are stable across releases.
Verify a download against SHA256SUMS: shasum -a 256 <file> on macOS, sha256sum <file> on Linux, certutil -hashfile <file> SHA256 on Windows.
macOS#
Open the disk image, drag HTML Clay into Applications, and open it once. The app lives in the menu bar and has no main window. The app bundle is what registers .htmlclay as a document type.
htmlclay is not on PATH on macOS. The binary lives inside the app bundle, so the wire CLI needs an alias:
alias htmlclay="/Applications/HTMLClay.app/Contents/MacOS/htmlclay"
Put that line in ~/.zshrc to keep it across terminal sessions.
Windows#
Unzip the download somewhere you will keep it, then run htmlclay.exe once. It writes the .htmlclay association under HKCU\Software\Classes, so the normal path needs no administrator prompt, then stays in the system tray. It also adds HTML Clay to the Open With list for .html and .htm without taking those extensions away from the browser.
Every launch refreshes the registration, so after moving the executable, run it once from its new location. register.bat in the archive is a fallback for machines whose policy refuses the app’s normal per-user registration.
To remove the associations and the Start on Login entry without touching documents, settings, or backups:
htmlclay.exe --unregister
Linux#
Unpack the tarball, open a terminal in that folder, and run the installer:
bash install.sh
The default installs the binary into ~/.local/bin and writes a freedesktop MIME entry, a desktop entry and icons under ~/.local/share. It never asks for sudo. bash uninstall.sh reverses it. Two overrides exist: bash install.sh --system installs into /usr/local/bin and does use sudo, and BIN_DIR=/some/path bash install.sh picks any other directory.
Permission dialogs need zenity, falling back to kdialog. With neither installed every prompt fails closed, so a file outside an already trusted folder is refused. Folders trusted from the tray still work.
From Go source#
Go 1.26 or later:
go install github.com/panphora/htmlclay/cmd/htmlclay@latest
That gives the tray app, the local server, and the htmlclay wire CLI. On Windows it also gives double-click association, because the binary registers that itself. On macOS and Linux the association lives outside the binary (in the .app bundle’s Info.plist and in the freedesktop MIME database), so use a packaged build if you want double-click to work.
From a checkout, the Makefile targets are make build, make test, make dist-macos, make dist-linux, make dist-windows, make clean.
Make the file#
Use a plain text editor, then copy the complete checklist below.
In TextEdit on a Mac, choose Format, then Make Plain Text. In Notepad on Windows, set Save as type to All files.
Keep your internet connection on while using this starter. It loads its editing library, ClayJS, from clayjs.com. HTML Clay does not upload your file.
In my-list.htmlclay:
<!DOCTYPE html>
<html lang="en" autosave>
<head>
<meta charset="utf-8">
<title>My list</title>
<style>
body {
font-family: system-ui, sans-serif;
max-width: 30rem;
margin: 3rem auto;
padding: 0 1rem;
}
.item {
display: flex;
gap: 0.6rem;
padding: 0.3rem 0;
}
</style>
</head>
<body>
<h1 editable>My list</h1>
<div class="item">
<input type="checkbox" persist aria-labelledby="item-1">
<span id="item-1" editable>Make my first file</span>
</div>
<div class="item">
<input type="checkbox" persist aria-labelledby="item-2">
<span id="item-2" editable>Check something off</span>
</div>
<div class="item">
<input type="checkbox" persist aria-labelledby="item-3">
<span id="item-3" editable>Close the tab, then open the file again</span>
</div>
<div editable>
<p>This part is for notes. Click anywhere and type.</p>
</div>
<script src="https://clayjs.com/v1/clay.js?plugins=indicator"></script>
</body>
</html>
Paste it into the editor and save it on your Desktop as my-list.htmlclay. If the editor asks about the extension, keep .htmlclay.
Open it and make a change#
Open my-list.htmlclay from your Desktop. It opens in your default browser, at an address like http://htmlclay.localhost:1212/my-list.htmlclay. An address ending in .localhost means HTML Clay is serving the page from your own computer.
Check the first box, edit the second item, and type a note. Wait until a small chip in the bottom right says Saved. There is no save button.
Close the tab, then open the file from your Desktop again. Your checked box and words are still there because they were written into my-list.htmlclay.
See it in the file. If my-list.htmlclay is still open in your text editor, close it without saving. Then reopen it. The first checkbox now contains checked:
<div class="item">
<input type="checkbox" persist="" aria-labelledby="item-1" checked="">
<span id="item-1" editable="">Make my first file</span>
</div>
Browsers write bare attributes such as persist as persist="". HTML Clay also adds documentid to the root <html> tag for backup history. Both are normal.
If it did not work#
- You see code instead of a checklist: save the file as plain text and confirm its name ends in
.htmlclay, not.htmlclay.txt. - The file does not open with HTML Clay: on Windows, run
htmlclay.exeagain. On Linux, reruninstall.sh. On a Mac, select the file in Finder, then choose File, Open With, and HTML Clay. - Nothing is editable or saves: reconnect to the internet, then reload the page.
How saving works#
A browser cannot write to your disk by itself. HTML Clay serves the file to your browser and writes each save back into that file. ClayJS runs inside the page and turns your edits into HTML for HTML Clay to save.
A minimal .htmlclay file#
The recommended way to make a file malleable is ClayJS, a separate MIT-0 library loaded from a CDN. HTML Clay never injects a script into your page; the page brings its own.
<!DOCTYPE html>
<html lang="en" autosave>
<head>
<meta charset="utf-8">
<title>My list</title>
</head>
<body>
<h1 editable>My list</h1>
<div class="item">
<input type="checkbox" persist aria-labelledby="item-1">
<span id="item-1" editable>Make my first file</span>
</div>
<div editable>
<p>This part is for notes. Click anywhere and type.</p>
</div>
<script src="https://clayjs.com/v1/clay.js?plugins=indicator"></script>
</body>
</html>
Save it as plain text with a .htmlclay extension, put it anywhere inside your home folder, and double-click it. It opens at an address like http://htmlclay.localhost:1212/my-list.htmlclay, its folder’s own hostname on the app’s one port. You can also open it from a terminal with htmlclay my-list.htmlclay.
The three attributes that did the work, all documented in the ClayJS Attributes reference:
| Attribute | Where | Effect |
|---|---|---|
autosave | the <html> element | saves after edits settle |
editable | heading, paragraph, span, div | click into it and edit its contents as rich text |
persist | checkbox, text field, textarea, radio, select | writes the control’s value into the file |
Command+S on macOS, Control+S elsewhere, saves at once. There is no save button.
The plugin list on the loader URL is ?plugins= comma separated, in the ClayJS script tag. Loadable plugins: richclay (on by default), indicator, sync, sortable, undo, cms, quickcrop, upload, wire, demo. Remove a default-on plugin with ?exclude=. The complete ClayJS reference is at clayjs.com/llms.txt.
ClayJS is client-side, so a file that loads it from https://clayjs.com needs network access for that one script. Download ClayJS beside your file and point the script tag at it to work entirely offline. HTML Clay itself never uploads the document.
A file needs no library at all. The save endpoint is a plain POST, and this is the whole of it:
<button id="save">Save</button>
<script>
document.getElementById('save').addEventListener('click', async () => {
const html = '<!DOCTYPE html>\n' + document.documentElement.outerHTML;
const token = document.documentElement.getAttribute('savetoken');
const res = await fetch('/_/save/' + token, {
method: 'POST',
headers: { 'Content-Type': 'text/html' },
body: html
});
if (res.ok) document.title = 'Saved!';
});
</script>
Good to know#
- The file remains ordinary HTML. Rename it from .htmlclay to .html and a browser can open the saved contents. Without HTML Clay, further changes are not written back into the file.
- HTML Clay keeps recent backups when it can. If a change goes wrong, choose Backups from the menu bar or tray icon to find earlier copies of the file.
- Files must stay inside your home folder. HTML Clay refuses to open a file outside it.
Where next#
- Build your own file. Learn the ClayJS attributes and start from plain HTML.
- Use several files together. Learn about Trusted Folders, backups, live sync, and the safety boundary.
- Let a local program edit the file. Connect a script or coding agent to the file.
One file. Yours.