.curt

released · npm ↗︎· MIT· shipped Oct 16, 2026

One file, one conversation, kept whole. The open format for AI chat history.

Open single-file format for AI conversations — frozen spec v1, MIT everything, 27 conformance vectors in CI, curt-format on npm.

v1, frozen spec27, in CI conformance vectors5 (2 stable, 3 draft) extensionsMIT — spec, code, schema, fixtures license

Your AI history is files, not hostages — the line is Curtis’s, and .curt is where it stops being a slogan. Spec v1 is frozen. [email protected] is on npm, MIT, zero dependencies. Twenty-seven conformance vectors run in CI so “compatible” means something. Curtis Porter reads the hostile exports — ChatGPT branch trees, Claude content blocks, Grok archives, Gemini Takeout — and writes .curt.

The honest score: six registry entries, one author, zero outside consumers. That’s what a launch looks like before it launches. The spec is here, the adopt path is here, and the launch post tells it straight.

Install

Features

Full fidelity or it's not a .curtBase64 images and tool calls ride in content, verbatim. Unknown fields survive a re-save — an app's extras are never a liability. One diffable UTF-8 file per conversation: archives, version control, and grep all just work.
Frozen coreThe spec doesn't move. New capability means a named, versioned, optional registry entry — never an edit to v1. Readers reject extensions they don't know, cleanly and whole. A format that can't break its readers is a format you can build on.
Conformance is testableL1 CORE through L4 per-extension — 27 executable vectors, plain fixtures, CI-runnable. "Compatible" is a claim you can check, not an adjective.
The two-implementation ruleAn extension goes draft → stable only when two independent implementations round-trip it. One author stamping their own work stable is how formats rot. consensus-receipt needs one more implementation — yours would do it.

How it compares

.curtVendor exportsAd-hoc JSON / markdown
Images & tool callsVerbatim, in-fileFlattened or droppedVaries by author
Unknown fields on re-savePreservedN/A — opaque schemaUsually lost
Machine-checkable conformance27 vectors, CI-runnableNoneNone
One file per conversationYes — diffable UTF-8One giant archiveVaries
LicenseMIT — spec, code, schema, fixturesVendor termsVaries

Privacy

A .curt file is a plain UTF-8 file — there is nothing to telemetry. The reference implementation makes zero network calls: serialize, parse, done.

FAQ

Why not just export markdown?Markdown is a rendering, not a record. It drops or mangles images, tool calls, usage data, and structure — the parts that make a conversation reusable. .curt keeps all of it, and markdown-from-.curt is a one-liner whenever you want it.
Who controls the spec?One maintainer, BDFL — deliberately. The core is frozen at v1, so control is smaller than it sounds: evolution is registry-only, and readers must reject unknown extensions cleanly, so nothing breaks under you.
Curtis apps are BUSL — is the format locked too?No, and the split is the point: the format, reference code, schema, and fixtures are MIT. Build a business on .curt. Only Curtis applications themselves are BUSL.
How does my app get listed?Implement against curt-format, run the conformance vectors, then PR against capabilities.json in the dot_curt repo: who you are, what you read and write, which extensions, conformance level. It's public and checkable — that's the feature.