Import · JSON, Markdown, or hash-URL

Three import paths. No upload, ever.

Pick a JSON file, drag in a Markdown bundle (Pro), or open a hash-URL a teammate sent you. All three resolve in this tab. The bytes are parsed, validated, and merged by id against your existing library without leaving the browser. The file path also reads exports from ChatGPT, Claude, Cursor, fabric, and CSV, so the library you built elsewhere comes with you. There is no server to receive the file - the upload step doesn't exist because the upload doesn't happen.

Typical import: under 200 ms for 50 prompts. No account.

  • 0 uploads
  • Validated locally
  • Merged by id
my-prompts.import.json Your file
// Minimal import payload · schemaVersion 3
{
  "schemaVersion": 3,
  "prompts": [
    {
      "id": "pr_a14b",
      "title": "Weekly status update",
      "body": "Summarize {{ project }} for {{ audience }}...",
      "tags": ["writing", "status"]
    },
    {
      "id": "pr_91c2",
      "title": "Code review - security pass",
      "body": "Scan {{ diff }} for auth and escape issues.",
      "tags": ["code", "review"]
    }
  ]
}

file is 480 bytes · validated locally · merged by id

Pick the one that matches the source.

Most imports come from one of three places: a JSON file someone sent you, a Markdown bundle you exported from Pro, or a link a teammate dropped in chat. Every path lands in the same place: IndexedDB on your machine, validated against the schema before a single prompt is written.

Hash-URL share link format: #import=<base64-json> · max: 100 kB encoded
// What a share link looks like
https://promptorganizer.app/app/#import=
eyJzY2hlbWFWZXJzaW9uIjozLCJwcm9tcHRzIjpb
eyJpZCI6InByX2ExNGIiLCJ0aXRsZSI6Ildl...

// What happens when you open it
1. The page loads. No network call to fetch the payload.
2. The hash is decoded in the browser.
3. The payload is validated against the schema.
4. You see a confirm step before anything writes.
5. Prompts merge by id into your existing library.

// The link is the payload.
// Nothing was uploaded to send it.
  1. 1. File via the file picker.Drag a file in or use the picker. Native JSON re-imports anything you've exported, and the same path recognizes exports from ChatGPT, Claude, Cursor, fabric, and plain CSV. Validated, then merged by id.
  2. 2. Markdown bundle (Pro).If you keep prompts as Markdown files alongside notes - one prompt per file with frontmatter - drop the bundle in and Pro parses it into the library. Frontmatter keys map to fields; the body becomes the prompt body.
  3. 3. Hash-URL share link.Someone pasted a long URL with #import=... at the end. The payload is encoded into the link itself. The browser decodes it locally - the share happened over the link, not through us.

Strict on the way in. Permissive on the way out.

The import limits exist because the bytes are running through your browser, not a backend with a queue and a rate limiter. A 5 MB payload from a stranger's link could lock the tab for seconds. So imports are capped at sizes a browser handles without flinching.

Validation runs before anything is written. If the schema is wrong, the import fails closed and your library is untouched. If two prompts share an id, the existing one is kept and the difference is surfaced - no silent overwrites, ever.

  • 100 kB encoded payload max.Generous for prompts; small enough to decode and validate without UI jank. Larger libraries import as a JSON file, not a hash-URL.
  • 50 prompts max per import.A pack, not a vault dump. Vault restores use the regular vault file, which has no count limit.
  • 50,000 characters per field max.Generous for system prompts and bodies, hard cap to prevent accidental megabyte pastes.
  • FNV-1a checksum on vault payloads.Vault files carry a checksum. Mismatched files are flagged on import; you confirm before the library is touched.
  • ID-based merge, no silent overwrites.An incoming prompt with an existing id surfaces a diff. You pick: keep, replace, or duplicate. The default is keep.
  • Schema-version aware.Older schemas are upgraded in-memory before validation. Newer schemas are rejected with a readable error pointing at the version field.

Drop the JSON in. Confirm the diff. Done.

Open the importer Or seed the starter pack

Three things you can check yourself.

Hash imports are local. Open dev tools, paste a #import= URL, and watch the network tab. The hash is read by JavaScript already in your tab. There is no request that carries the payload anywhere.
Conflicts surface explicitly. Import a JSON file that contains a prompt id you already have. The app shows a side-by-side diff and asks. Default action is keep-yours. No prompt is replaced without a click.
Schema documented. The schema is plain JSON with named fields. Open any vault export in a text editor and you can write an importable file by hand. No proprietary container, no opaque encoding.

No upload. No round-trip.

The import flow is a file picker, a schema check, and a write to IndexedDB. That's the whole thing. Open the app, pick a file, confirm the diff. Nothing left the tab.