There is a million characters of ChatGPT and Claude conversation on my laptop. Export files: complete, backed up, unreadable. So I built Recto, a local reader that lays them out as a searchable, annotatable book.
Seventeen sessions, most of them genuinely useful while they were happening. Design arguments, debugging trails, decisions I would otherwise have forgotten by now.
I never read any of it again.
Storage was never the problem. Claude Code keeps a JSONL log, ChatGPT and Claude export zips of JSON. The data is mine, it is complete, it is backed up. It just isn't readable. One long column of messages, no chapters, no index, no way to get back to the paragraph where we settled on something.
What it does
Recto takes an export, or your local Claude Code history, and lays it out as a book. Chapters with titles and a one line intro, plus a table of contents. Full text search over the whole library, not just the current conversation. Highlights in four colours with notes attached to them. An annotation list you can filter, and a margin rail for the long code blocks and tables that would otherwise wreck the page. Reading progress that survives you changing the font size.
All of it runs on your machine. Conversations are never uploaded, there is no account, there is no telemetry. Under the hood it's a small Python process serving a local page to your browser, which is the same shape as a lot of dev tools, just packaged for people who don't want a terminal.
What it does not do
I would rather say this before you download it than after.
- Windows only. No macOS build yet.
- It is not a chat client. It reads conversations you already had, it doesn't talk to ChatGPT for you.
- Import formats are limited: ChatGPT exports, Claude exports, local Claude Code history, and Doubao or Kimi through a bookmarklet. Gemini, Cursor and Copilot Chat are not supported yet.
- The AI features need your own API key, or the included trial. Reading, importing, highlighting, notes and search are free and stay free.
Three decisions worth explaining
1. No third party Python dependencies
The backend is the standard library. http.server, zipfile, urllib, JSON files instead of a database. PyInstaller for packaging, the installer comes out around 22 MB.
Some of that was a constraint, I wanted it to run on machines where pip is missing or broken. Most of it was a bet. Every dependency is one more thing that can fail on someone else's Windows install, and a desktop app that won't start is worse than an app with fewer features. The UI is plain HTML, CSS and JS with no build step, served from 127.0.0.1.
2. I removed the page numbers
The first version had page numbers. They were wrong, and not because of a bug. The idea is wrong for this medium.
A page number only works if it is a coordinate you can trust. Change the font size, or the column width, or the lines per page, and the whole book reflows. All of those are normal things to want to do. A coordinate that moves when you resize a window is not a coordinate.
So the reading position became chapter name, percentage through the chapter and through the book, and remaining word count. All three are independent of layout.
The interesting part is what that forced. If you can't point at "page 40", every highlight has to be anchored to something stable inside the content. Mine are anchored to message-id plus block and paragraph index, with a quote snapshot (exact, prefix, suffix) as a fallback for when the text shifts. When an anchor cannot be resolved it isn't dropped silently. It gets marked orphaned and listed, so you can re-attach it yourself. I lost 25 annotations to silent dropping once, which is why that list exists.
3. Licensing works offline
A purchase is a signed string, not a login: a base64 payload plus an Ed25519 signature. The client ships with the public key and verifies the signature locally. No activation server, no account, nothing phoning home.
The trade off is real: I can't revoke a licence, and I can't count activations. For a one time purchase of a local tool, that felt like the right side of the trade.
Two things I would like feedback on
If you try it, I would especially like to hear about these.
Does the chapterization hold up on long technical conversations? Right now it can run offline with heuristics over message boundaries, or it can ask your own model to do it. My guess is the answer depends on the kind of conversation, and I want to know which kind it gets wrong.
Which import format should come next? Gemini, Cursor, Copilot Chat, or something I haven't thought of.
Try it
It's on the Microsoft Store. Search for Recto Book, or use this link: https://apps.microsoft.com/detail/9P1F472V522J
Every copy includes a self serve 7 day trial of the AI features. No email, no card, no trial code. Reading, importing, highlights, notes and search are free permanently.
Launch price is $9.99 until 31 December 2026 or the first 100 paid licences, whichever comes first, then $14.99 one time. Details and the licence FAQ are on the purchase page: https://recto-privacy.netlify.app/buy.html
If it breaks on your export, mail me at GeRui2936@163.com and tell me the shape of the file. I don't need the content, just enough to reproduce the problem. No conversation text ends up in a bug report.


Top comments (1)
Author here — one thing I'd like help deciding.
Which export format should Recto support next? Today it handles ChatGPT (zip or JSON), Claude, local Claude Code history, and Doubao/Kimi through a bookmarklet. Gemini, Cursor and Copilot Chat are the obvious holes, but I'd rather build the one people actually have sitting on disk.
If you have an export you don't mind describing: which tool, and what shape is it — one JSON file per conversation, a single big array, a SQLite database? That's enough for me to estimate the work. I don't need the contents.
And if an import fails on your file, 0.3.3's "Copy error info" button gives version, size and container structure with no conversation text, so it's safe to paste here.