Search for this and you get SQLite compiled to WebAssembly, IndexedDB tutorials and a DuckDB demo in a 3.5 MB file. They are impressive and they answer a different question, because all of them store the data in the browser that is looking at the page. Your co-worker opens the same link and sees an empty list.
The question people are actually asking is: how does one HTML file hold state that more than one person can see. Below are the four honest answers, with the trade you make in each.
The four options, in the order most people should try them
| Option | Shared between visitors | Setup | Free tier |
|---|---|---|---|
| Hostus, page storage | Yes | Drop the HTML, call hostus.data | 1,000 records per collection |
| Claude artifact storage | Yes, if set to shared | Publish the artifact | No, paid plans only |
| Supabase or Firebase | Yes | Project, table, keys, rules | Yes, generous |
| IndexedDB, localStorage, sql.js | No, one browser only | None | Free |
The last row is the trap. It is free, it needs nothing, and it works perfectly on your machine, which is exactly why so many pages ship with it and fall over the first time two people use them.
What page storage actually is
On Hostus, a document is an HTML file with a URL. If the page references hostus.data, the server injects a small SDK before your script runs, and the page can read and write records that belong to that document.
const { data } = window.hostus;
data.watch("rsvps", (items) => render(items)); // now, and on every change
await data.add("rsvps", { name, going: "yes" }); // one record
await data.set("rsvps", key, { ...value, going: "no" });
await data.remove("rsvps", key);There is no API key in that snippet and there is nothing to configure, because the server already knows two things the page does not: which document this is, and who is reading it. A visitor who is not logged in gets a signed cookie, which is enough to mark their own records as theirs without asking them to sign up for anything.
Who can see what
Three modes, set on the document, not in the page:
- Shared, the default: every reader reads and writes everything. Right for a checklist, a tally, a guest list.
- Per reader: each visitor sees only their own records, and you see all of them. Right for private answers, individual progress, a booking request.
- Owner only: everyone reads, only you write. Right for a published list you keep updated.
You can also freeze a page: the document stays up and readable, and nobody can write to it any more. Useful the day the sign ups close.
Three live pages you can poke at
These are on the free plan and the records in them are real, written by whoever opened the link before you.
- RSVP for a supper: add your name, watch the counter move.
- Pick a Thursday: one vote each, and you can move yours.
- A launch checklist: tick a box and it stays ticked for the next person.
Each is a single HTML file, around 6 KB, with no build step and no dependency beyond a font.
When you should use a real database instead
Page storage is records in collections, capped at 8 KB per record, 20 collections per document and 1,000 records per collection on the free plan, 20,000 on paid. That covers almost every page that starts life as "can people just add their name".
Go and get Supabase or Firebase when you need any of: queries across records, user accounts with roles, transactions, a relational join, or data that has to outlive the page it belongs to. Those are databases, and this is not one.
Good to know before you switch
The storage only works while the page is hosted on Hostus, because the server is what resolves who each reader is. The HTML is yours and downloads in one click, but a copy of it opened from your desktop shows an empty list.
There is also no dashboard for the records. You read them from the page itself, or you ask Claude, which has a hostus_data tool that lists collections and returns their contents. If you want a spreadsheet view of everything, this is not that yet.