← All posts

How to save the data people enter into an app you built with AI

Your AI-built app forgets everything when the tab closes. Here's how to give it real storage, shared data, per-user data, shared posts, and form captures, without standing up a database.


You built a form, a tracker, or a little tool with AI, and it works, until someone closes the tab and everything they typed is gone. An app that doesn’t remember isn’t really an app people can use. Here’s how to give a single-page HTML app real storage without becoming a backend engineer.

The quick answer

Host the app on Backlit and use its built-in storage from your HTML: window.backlit.data for shared data, window.backlit.userdata for data that’s private to each signed-in person, and window.backlit.capture for write-only form submissions. There’s no database to set up. Storage comes attached to the app.

Why AI-built apps forget

A single HTML file has no memory of its own. Anything it “stores” usually lives in the browser tab, in a JavaScript variable or, at best, in that one browser’s local storage. That means:

  • Refresh the page and it may be gone.
  • Open it on a different device and there’s nothing there.
  • Two people using the app never see each other’s data.

For a throwaway calculator that’s fine. For anything you’d share (a roster people update, a form that collects replies, a tracker the family adds to), you need data that lives safely on a server, outside the browser. That’s the part the AI didn’t (and shouldn’t) bake into your file.

The four kinds of “saving” you actually need

Not all data is the same, and that’s the thing most people miss. Backlit’s storage layer, Ember, gives you four surfaces because real apps use all of them:

  • Shared data: one set of data the whole app sees. A team’s task list, a household shopping list, a public leaderboard. Anyone with a valid session can read and write it.

    await window.backlit.data.put("tasks", tasks);
    const tasks = await window.backlit.data.get("tasks");
  • Shared posts (records): a shared collection any signed-in person can add to, and everyone can read, but only the author (or an admin) can edit or remove an item. This is the surface people miss: it’s what makes comment walls, team boards, and community posts work, with no backend.

    await window.backlit.records.putJSON("comment." + id, { text });
    const { items } = await window.backlit.records.list("comment.");
  • Per-user data: a private silo for each signed-in person, keyed to their verified email. One user can never see another’s. Perfect for “my settings,” “my entries,” “my saved items.”

    await window.backlit.userdata.put("prefs", prefs);
    const prefs = await window.backlit.userdata.get("prefs");
  • Captures: a write-only store for form submissions and telemetry. Your app can drop a response in but can’t read the pile back out, which is exactly what you want for a contact form or survey where the visitor shouldn’t see everyone else’s answers.

    await window.backlit.capture.create("signups", formData);

Choosing the right one is most of the design. A booking form? Captures. A personal tracker? userdata. A shared board? data. A comment wall where everyone posts and reads? records.

How to add it to your app

If your app already runs on Backlit, the storage is already there. You just call it. The easiest route:

  1. Tell your assistant what should persist: “save the task list to Backlit shared data, and keep each user’s filters in their own userdata.”
  2. It wires the window.backlit.* calls into your app’s existing logic.
  3. Publish. Now the data survives refreshes, devices, and people.

No connection strings, no schema, no separate database service to sign up for.

What you get for free

  • Isolation. Per-user data is separated by verified email. There’s no way for one user to read another’s silo.
  • Region pinning. Your data stays in the region you pick (Australia or the US) and isn’t copied across regions.
  • Integrity and history. Writes are checksummed, and prior versions are retained so a bad save isn’t the end of the world.
  • Sensible limits. Each plan includes storage (500 MB free on Spark, more on paid plans), and you can add capacity with Amp storage packs if an app gets popular.

What it deliberately doesn’t do

Ember is key-value storage, not a full relational database with complex queries and joins. That’s on purpose: it keeps the API to a handful of calls you can hold in your head, and keeps the whole thing fast and cheap. If your app genuinely needs a query engine and relational modelling, it’s outgrowing the category Backlit serves.

For the vast majority of shared apps, though, “remember this per user, remember that for everyone, and collect these submissions” is the entire data story, and you can have it without ever touching a database. Storing is only half the loop: because the same MCP that deploys your app can read its data back, you can query or export everything straight from Claude when you need it (how to get your app’s data back out). Read the FAQ → or see how it works →.


Built an app with Claude or ChatGPT? Get started with Backlit and share it in seconds.