NOW PLAYING · SOLO BUILD
2026 — live
hearth
A journal that remembers — on a server that can be made unable to read it.
An AI-first journaling app across web, iOS and Android. Entries are written, spoken or photographed, encrypted in the browser before they go anywhere, and queryable — by its own AI companion, or by your assistant over MCP. Turn on Private Vault and the backend loses the ability to decrypt you at all.

- 230K
- LINES OF CODE
- 471
- TEST FILES
- 3
- SHIPPED SURFACES
- 0
- PLAINTEXT STORED
the problem
Every journaling app asks for the same thing: write your worst week down, and trust us with it. The trust is the product, and almost none of them let you check it. “We take privacy seriously” is a sentence, not a guarantee — and the moment an app adds AI, your diary is one training run or one support ticket away from being read.
The other half of the problem is that a journal you can’t ask anything is a drawer. Years of entries, and no way to answer “what was I like last winter” without scrolling. The feature everyone actually wants is the one that seems to require handing over the plaintext.
Hearth exists to have both: a journal that answers questions, and a privacy claim you can verify rather than believe.
how it works
Entries are envelope-encrypted in the browser before they leave it. The API only ever stores ciphertext and wrapped keys — in every mode, on every tier, including free. Photos are resized and stripped of location on-device first; voice entries are transcribed to text you can edit before anything is sealed.
In the default managed mode the server can decrypt transiently — to unlock a session, and to answer a question your assistant asks over MCP — and keeps nothing from that path. Turn on Private Vault, free on every tier, and the server’s escrow key is destroyed: “we don’t read it” becomes “we cannot”, and the AI features that need plaintext go with it. That trade belongs to the user, which is the entire point.
Both halves are pinned by tests rather than by copy: a documented invariant maps each privacy claim to the test that would fail if it stopped holding. Journal plaintext is never persisted server-side and never logged, and the suite is what says so.
The companion, Inkling, is drawn by code rather than shipped as art — a platform-free engine of spring physics, a 24-channel rig, moods and reactions, painted with Canvas 2D on the web and Skia on native. It ships no image assets, which is why it behaves identically on three surfaces from one implementation.
▸ ATTRACT MODE
the rest of the screens.

▸ RUNS ON
the back of the box.
- web
- React 19TypeScriptVite 7Redux ToolkitTailwind v4vite-plugin-pwai18next
- mobile
- Expo 57React NativeSkiaReanimated 4MMKVRevenueCat
- api
- Go 1.26chipgxPostgreSQL60 migrations
- crypto & auth
- libsodiumenvelope encryptionpasskeys / WebAuthnOIDCrotating refresh families
- ai
- Vertex AI Geminizero-retention laneMCP serverRAG corpus
- infra
- Cloud RunFirebase HostingGCSResendGitHub Actions
- tests
- 146 Go suites178 vitest94 Playwright specstwo viewportsjest-expo
▸ GAME OVER · CONTINUE?
the bit that bit.
deploy-api and deploy-web don’t wait for ci — all three run in parallel on the same push, so a red gate never held a release. I found that out the flattering way: a clean deploy sitting on top of a failing build.