Local-first · Defined technically · v3.0

A workbench that runs in your tab.

"Local-first" is overloaded as a marketing word. Here's what it means for Prompt Organizer, mechanically: static HTML, CSS, and JavaScript served from a CDN. Your prompts written to IndexedDB on your disk. No server endpoint that accepts a prompt. A portable JSON vault you can read in any text editor. Privacy promises from cloud apps are policy documents. Privacy from a local-first app is a thing you can observe.

Open dev tools. Watch the network tab. That's the whole proof.

  • 0 app servers
  • 0 bytes sent
  • 1 portable file
promptorganizer.app/app
Network activity
NameStatusTypeSizeTime
app.html200document14.8 kB12 ms
app.js200 · cachescript-2 ms
app.css200 · cachestylesheet-1 ms
mark.png200 · cachepng-1 ms

All prompt activity stayed local

Created 4 prompts. Edited 2. Tagged 6. Imported a pack. Zero prompt-library requests sent to our servers.

Illustration. Verify it yourself: open the app, then your browser's Network panel.

Mobile summary: after the page loads, prompt activity makes 0 app network requests.

Local-first, defined technically

Four claims. Each one verifiable.

"Local-first" gets used to mean a dozen different things - sometimes "we sync, but optimistically", sometimes "your data goes to our cloud but encrypted". Here it means something narrower and more checkable.

What actually loads first paint · nothing after
// First open
GET /app/                  200  document    14.8 kB
GET /css/app.css           200  stylesheet  31 kB
GET /js/app.js             200  script      82 kB
GET /js/storage.js         200  script      18 kB
GET /favicon.ico           200  png         1.1 kB

// After first paint, while you work
· save a prompt        -> 0 requests
· edit a prompt        -> 0 requests
· search the library   -> 0 requests
· import a JSON file   -> 0 requests
· export the vault     -> 0 requests

// What this implies
There is no app server to send prompts to.
Static files cannot receive a POST.
  1. 1. Static HTML, CSS, and JavaScript served from a CDN.The app is a folder of files. A CDN serves those files. There is no application server, no API backend, no database we own.
  2. 2. IndexedDB on your disk.Every prompt, tag, reference, and SKILL package is written to the browser's IndexedDB on your machine. The data lives in a file under your user profile - not on our infrastructure.
  3. 3. No server endpoint for prompts.There is no URL we expose that accepts a prompt body. Even if we wanted to receive your library, there is nowhere to send it.
  4. 4. Portable JSON vault.One file. Plain JSON. Human-readable. Schema documented. You pick where it lives - your disk, your Git, your iCloud. We never see it.

Run the proofs yourself. They take a minute.

Open dev tools. Network tab. Reload the app. After the static files load, save a prompt and watch the row count: it doesn't move. Compare to any cloud app where every keystroke is a request.
Inspect IndexedDB. Application tab, IndexedDB, promptOrganizer. There's your library, in a database file on your disk, indexed by id. You can see every prompt body, every tag, every reference.
Look at the URL list. Every request the app makes is for a static asset under /css/, /js/, or /images/. There is no /api/, no /v1/, no /prompts. Browse the source on GitHub if you want to confirm.

Where your prompts actually go

1 You type a prompt browser · this tab
2 IndexedDB on your disk ~/Library/Caches/...
3 Server there isn't one

The third box doesn't exist. The app is static HTML, JS, and CSS served from a CDN. There is nowhere for us to receive your prompts even if we wanted to.

Privacy, durability, portability - by architecture, not by promise.

Privacy. The prompts you refine reflect your judgment, your clients, your evaluation criteria. They aren't search queries; they're trade secrets in 200 words. A local-first app can't share what it never receives. Your IT admin doesn't see a Prompt Organizer dashboard with your library on it. There is no such dashboard.

Durability. The library survives us. If Prompt Organizer goes away tomorrow, you still have a 67 kB JSON file on your disk. Open it in vim. Diff it in Git. Hand it to a new tool that knows how to read JSON. The vendor risk is bounded at "I might need to find a new editor for this file."

Portability. The vault is yours in the strong sense: it lives on your filesystem, in a format you can read, with no proprietary container or DRM. Move it to a different machine. Sync it through iCloud. Email it to your future self.

~/Vaults/prompt-library.vault.json Your file
// Plain JSON · schemaVersion 3 · FNV-1a checksum
{
  "schemaVersion": 3,
  "storage": "local-only",
  "server": null, // there isn't one
  "checksum": "a14b...f9c2",
  "prompts": [
    {
      "id": "pr_8f3a",
      "title": "Weekly status update",
      "body": "Summarize {{ project }}...",
      "tags": ["writing", "status"]
    }
  ],
  "refs": [],
  "skills": []
}

67 kB · belongs to you · revoke nothing

Where else would you keep these?

An honest look at the three options most people land on by default, and the structural tradeoffs each one is quietly making.

On small screens, each row stacks so every tradeoff is readable without sideways scrolling.

Local-first workbench static · no account Cloud-hosted notes Notion / Google Docs Vendor prompt UI ChatGPT / Claude history
StorageIndexedDB on your machineVendor's databaseVendor's database
Training riskNone - we don't have the dataVendor AI features may trainDepends on plan and toggles
Durability if vendor disappearsIt's a file on your diskLocked behind loginLost
Portability across toolsJSON, 19 send-to destinationsCopy-pasteTrapped in one vendor

Your craft deserves a place that respects it.

A local-first workbench isn't a smaller cloud app. It's a different shape of software - one that runs in your tab, writes to your disk, and exits when you close it. The library you build today is still yours in five years, whether we're here or not.