Projects

Echo: Private, Local-First AI Journaling

Founder & Lead Developer

2025-01-15

ReactLangChainOllamaPostgreSQL

Echo on GitHub


Context

I built Echo in early 2025. It's a journaling app, but with a hard constraint: the user's data never leaves their device. The whole thing runs locally, so the LLM, the embeddings, the database — all of it is on your machine.

I was the founder and sole developer.


Problem / Product Goal

Journaling produces the most private data you own. So asking someone to pour their deepest thoughts into a text box that gets shipped off to a third-party API for "analysis" feels wrong. Actually, it's worse than wrong — it breaks the whole thing. If a user doesn't feel safe, they won't be honest. If they aren't honest, the journal loses its value.

The standard trade-off in AI apps is: you want smart features, you give up your data. For a journal, that trade-off kills the product entirely. The goal was to break it — build something that could offer meaningful AI-powered reflection without ever transmitting the user's thoughts to a server.


Thought Process

Most of the hard work was figuring out how to run everything locally without making the experience feel janky.

I started with Ollama as the inference engine. It runs models like Llama 3 and Mistral directly on the user's hardware. No network calls, no data leaving the machine. The trade-off is model quality — open-weight models aren't as capable as GPT-4 — but for journaling, you don't need cutting-edge reasoning. You need something that can read a week's worth of entries and surface patterns. Local models handle that fine.

The RAG pipeline was the next challenge. A user writes an entry, it gets embedded locally, and the vector goes into a PostgreSQL store with pgvector. When they ask something like "how has my mood shifted this week?", the system finds relevant past entries and feeds them into the local LLM for a synthesized response. All of this happens on-device. No data leaves.

The design decision was just as important. Most productivity apps are cluttered — buttons, notifications, charts. I wanted Echo to feel quiet. Swiss-inspired minimalism: high contrast, dark aesthetic, subtle glows, nothing drawing attention away from the text. When you open the app, you see your journal, not a dashboard.


Solution

The architecture rests on two pillars.

Local LLM Inference via Ollama. The journaling model runs on the user's machine. There are no cloud roundtrips, no data leaks, and zero API costs. It's slower than a cloud call, but for a journaling app where you're writing and reading at your own pace, the latency doesn't matter.

Retrieval-Augmented Generation. Write an entry → embed it locally → store the vector → on query, retrieve relevant past entries → feed them into the LLM for a context-aware reflection. The loop stays entirely inside the user's machine.

The result: a journal that can answer questions like "what themes keep coming up for me?" or "when did I last feel this way?" — without ever transmitting a single word to a server.


Takeaways

Privacy isn't a constraint, it's a feature. Most products treat privacy as a cost center — something you have to add on top. For Echo, the privacy requirement drove every architectural decision and made the product better. Users who care about this stuff (and journaling users definitely do) will choose a worse product that respects their data over a better product that doesn't.

Local models are good enough for this use case. You don't need Claude to summarize a journal entry. Open-weight models running locally handle the task fine. The bottleneck isn't reasoning quality — it's making the RAG pipeline reliable enough that the model has the right context to work with.

100+ users in the first few months, all of whom made a deliberate choice to run software on their own hardware for the sake of privacy. That's a real signal.

Next step was full WebGPU support via WebLLM — remove the Ollama dependency entirely and let Echo run in a browser with no install at all. Zero-install, zero-leak, zero-compromise.