Privacy
Last updated 10 August 2026. This is version 1.1 of the product, and this page describes what version 1.1 actually does.
Your books are opened by your browser, on your device, and by default they stay there: no upload, nothing sent anywhere. The one thing that changes that is signing in: it turns on sync, which stores a copy of your library in our own cloud so your other devices can pick it up. This page says, in plain terms, exactly what that does and does not involve.
Your books
When you drop an EPUB or a PDF onto the reader, the file is stored by your browser on your own disk, in the Origin Private File System, with the shelf entry and your place in the book in IndexedDB. If you stay signed out, none of it is sent anywhere; there is nowhere for it to go.
Signing in is the exception, and it is opt-in; see Signing in, and sync below. Until you sign in, no server of ours ever receives a book.
You can take everything out at any time: Export my library on the shelf writes a zip containing every book file and a manifest of your reading positions, saved by your browser like any other download. Removing a book from the shelf deletes its bytes, not just its row.
Signing in, and sync
Sync is opt-in and off until you sign in. It exists for one thing: so your shelf and your place in a book follow you from one device to another.
Signing in uses Google. We ask Google for only a stable, opaque account id and your email address, nothing else, and we use them to keep your library apart from everyone else's. Your session is a first-party cookie and is shared with no one.
While you are signed in, your library is stored in our own Cloudflare storage, under your account: the book files themselves, kept as opaque files named after their own contents, with no titles attached, and, for each book, its format, its size, and your reading position. We hold them so your devices can share them; we do not otherwise inspect them.
Turning it off. Signing out clears this device's copy of your library, whatever the server says. Your synced copy stays in our storage, under your account, until you remove it: deleting a book from the shelf deletes its file from our storage too, not just its row. To have the whole account and its synced library deleted, email CONTACT_EMAIL.
The voice
The neural voice runs on your device, and reading a book aloud sends none of its text anywhere. The first time you press Play, though, your browser has to fetch the voice model, and that is a real request to somebody else:
- The model is Kokoro-82M, downloaded from Hugging Face (huggingface.co). Like any file download, Hugging Face and their CDN see the request: your IP address, your browser, and which file you asked for. They do not see anything about your book, because nothing about your book is part of the request.
- It is between roughly 90 MB and 330 MB depending on your device, it is cached by your browser afterwards, and it is fetched once. After that the reader works with no network at all.
One honest exception, and it is the only place your book's words can leave your device.
If your device cannot run the neural voice fast enough, the reader falls back to your browser's own built-in voice, and tells you it has. Some browser voices run entirely on your device; others are network voices that send the sentence being read to the browser maker's servers to be spoken: Google's voices in Chrome and Microsoft's in Edge work this way. We ask your browser for its default voice and it does not tell us which kind it is, so we cannot promise you either way.
If that matters to you, use the neural voice, or pick a voice your system lists as offline in your operating system's speech settings.
What we count
Events, never identities, and only if analytics are switched on for a build; the public build ships with them off. When they are on, opening the reader or the landing page sends a short event to this site's own endpoint: an event name, the page you were on (the reader's own /app/, or the landing page, never a book), and one or two coarse properties, such as which voice tier your device landed on. That is the entire payload. There is no cookie, no identifier stored in your browser, no fingerprint and no profile.
How you are counted, and for how long. Because there is no cookie and nothing kept in your browser to recognise you by, the count is worked out on the server instead, and deliberately so it cannot follow you. When an event arrives, the server makes a visitor id by hashing together your network address, your browser's user-agent string, today's date, and a secret only the server holds. Two things follow from that recipe, and both are the whole point:
- Your raw address is never stored, and never logged. Only the hash is kept, and a hash cannot be turned back into the address it was made from without the secret, which never leaves the server.
- The id rotates every day. Because today's date is part of what is hashed, the same browser becomes a different id tomorrow. A single day's events can be loosely grouped; nothing can be joined back beyond that day. There is no history and no way to follow you from one day to the next.
The page you were on carries nothing about a book: no title, no filename, no position. Nothing in this list ever does. The complete list of events:
book_opened: with the format (EPUB or PDF) and whether it was the sample bookplay_pressed,listened_10m,second_book,returnedsession_duration: how long, in one visit, you were actively listening, in milliseconds, sent when the tab closes. How long, never how far and never where.floor_verdict_shown: your device was offered the browser's voicecta_clicked: you clicked the landing page's main button; and, if your browser told us, the site you arrived from, as a bare hostname (e.g.news.ycombinator.com) with no path and no querywaitlist_joinedfeedback: a thumb up or down, and the words you typed with it, if you typed any
Accounts. The paid tier syncs your library across your devices, behind a Google sign-in. If you sign in, the server counts, once, that an account exists, so we can see how many people signed up, and records a plain signed_in each time you do. Those counts carry no name, no email, and nothing that ties them to a visitor id. Your Google identity is used to keep your synced library apart from everyone else's and for nothing else; it is never handed to an analytics tracker, because there is no analytics tracker; see Hosting below.
That feedback line is the exception worth stating plainly. If you type something into the feedback box, we get what you typed. It is cut to 280 characters and stripped of any file path, and it is deliberately not put through the scrubber the crash reports use; that one deletes ordinary prose, which is exactly what you would be trying to tell us. So the box sends your words on purpose. Do not paste anything into it you would not want us to have; it is the only place on the site where you can type freely.
Crash reports
When the reader breaks, it can send us the error so we can fix it. Reports are switched off unless a build is configured to send them, and the public build sends nothing at all.
When they are on, a report carries three things, and by construction it cannot carry a fourth: the error's type, its message, and up to twenty stack frames. Before anything is sent, the message is put through a scrubber that
- removes runs of ordinary prose, which is what a page of your book looks like, and the way book text would otherwise end up in an error message;
- removes
file:,blob:anddata:URLs, which is where a filename or a book's bytes would otherwise be; - truncates what is left to 300 characters.
The error object itself is never sent. Only those three fields are copied out of it, so anything else the code attached, including a book, is left behind rather than filtered out.
The waitlist
If you give us your email address to hear when the paid tier ships, we store your address and the date you gave it to us. That is the whole record. We do not store your IP address alongside it, we do not log what you were reading, and we will not send you anything except the one email this is for.
To stop that, or to have your address deleted, email CONTACT_EMAIL and it will be removed.
Hosting, and what a web server sees
The site is served by Cloudflare Pages, and the waitlist and sync endpoints by Cloudflare Workers. Like every web host, Cloudflare processes the requests your browser makes (IP address, user agent, which page) to serve them and to stop abuse.
What analytics we do keep run on that same infrastructure, in our own account, and nowhere else. There are two pieces, and neither is a third-party tracker:
- Cloudflare Web Analytics counts pageviews, referrers and bounce rate. It is cookieless by design and sets nothing in your browser; Cloudflare measures the request its own edge already handled. There is no third-party script following you from site to site.
- Cloudflare Workers Analytics Engine is where the events listed above are written. It is our own store, in our own Cloudflare account. Nothing about you is sent to Google Analytics, to Plausible, to a data broker, or to any outside company: the endpoint the events reach (
/api/e) is this site's own, and the store behind it is ours.
What is kept in your browser
Three small entries in localStorage, none of which is a cookie and none of which is ever sent anywhere:
reader.seen: which one-time hints you have already been shown, so you are not shown them twice.reader.tier: which voice your device earned, so it is not re-measured on every visit.reader.metrics: which of the events above have already been counted for this browser, so a return visit is not counted twice, and how long you have listened. Written whether or not analytics are switched on, because it is what stops something being sent twice.
Clearing your browser's site data for this site removes them, along with your shelf and your books. Export first if you want to keep them.
Children
This is a reading tool with no account and no social features, and it is not directed at children under 13. We do not knowingly collect anything from anybody, which includes them.
Changes, and getting in touch
If this page changes in a way that matters, the date at the top changes with it. The version you are reading is kept in the project's public git history, so you can see exactly what changed and when.
Questions, or anything you think this page gets wrong: CONTACT_EMAIL.