Two months ago my desk had a stack of sticky notes on the monitor, a handwritten journal I kept forgetting to open, a OneNote tab for quick notes, and — if I'm honest — usually three or four Notepad windows open with things I didn't want to lose. None of it talked to each other. A task I jotted on a sticky note had no connection to the journal entry about the day I wrote it in. Finding anything meant digging through four different places and hoping I remembered which one.
I wanted one app that could handle two things I kept doing separately: journaling my day and tracking my tasks. So I built CapLog, a local-first desktop app where the log, the todos, and the history all live together in a single SQLite database.
The problem: a desk full of sticky notes and a dozen open Notepad windows
Most productivity tools make you pick a lane. Journaling apps are built for writing and treat tasks as an afterthought. Todo apps are built for tasks and don't want your rambling notes about how the day actually went. Cloud tools solve neither problem — they just add a login screen and a sync spinner to the same fragmented setup.
None of my existing tools were bad on their own. OneNote is fine for what it does. A paper journal is fine too. The problem was running all of them at once for one continuous stream of "what happened today and what do I still need to do." I wanted:
- a place to write a quick note about my day,
- a way to turn that note into something I could look back on,
- a place to capture tasks as I thought of them, without opening a second app,
- and a history I could actually search instead of flipping through notebook pages.
That's the gap CapLog fills. It isn't trying to replace every note app or task manager on the market. It's trying to be the one app I keep open while I work.
Why local, why desktop
I wanted CapLog to be local and secure, and those two things turned out to be the same decision. Local meant the data stays on my machine — no server holding my daily logs, no account to lose access to, no sync conflicts to resolve at 11 PM. Desktop meant no browser tab competing for my attention and no "sign in to continue" between me and a quick note.
Once I committed to desktop and local, the rest of the product got simpler to reason about. SQLite became the single source of truth. Export became "write a file to disk," not "call an API." And AI — which I wanted for formatting, not as a requirement — became something the app could do without. If AI is off or the request fails, CapLog just saves your raw text as a Markdown bullet. The app doesn't stop working because a network call didn't.
Security here isn't a checklist item, it's a side effect of the architecture: there's no application server in the middle, no custom backend API to secure, and no routine transmission of your logs anywhere. Data leaves the machine only when you explicitly turn on AI formatting or export a file.
What CapLog actually does
CapLog is deliberately small. You type into one input, and the app turns that into either a Markdown journal entry or a task, depending on what you type:
- Plain text becomes a log entry.
-
/todocreates a task. -
/importantmarks a high-priority task. -
/donecompletes an existing task.
If an AI provider is configured, it cleans up and formats the entry the moment you submit it. If it isn't, your text is saved exactly as you typed it, wrapped in a Markdown bullet. Either way, it lands in the same place: one local SQLite database, one feed, one history.
That's the entire interaction model. No folders to organize, no tags to maintain, no settings to tune before you can start using it.
How it's built: no backend, anywhere
CapLog is a Tauri v2 desktop app: a React and TypeScript frontend running in a native webview, with SQLite accessed directly through tauri-plugin-sql. The Rust side exists to host the window and wire up plugins — its invoke_handler is empty. There's no custom backend, and that includes the AI calls: when a provider is configured, the renderer talks straight to api.anthropic.com or an OpenAI-compatible endpoint over fetch(), using an API key stored in the local SQLite settings table.
The codebase follows a strict, one-directional layering: components handle UI, hooks connect the UI to data through TanStack Query, repository modules hold the SQL and return typed domain objects, and db.ts is the thin wrapper over SQLite. Only repos are allowed to touch db.ts — components never call the database directly. That rule keeps the UI from knowing anything about SQL, and it means the storage layer is isolated enough that it could be swapped out later without touching the rest of the app.
Data flow is just as plain. You type into the chat-style input, CapLog figures out whether it's a log entry or a slash command, formats it if AI is on, writes it, and TanStack Query invalidates the affected caches so the feed refreshes. Fewer moving parts between typing and saved data means fewer things that can break.
Content is stored as Markdown, not HTML, which keeps export simple and the renderer safe — CapLog uses a Markdown renderer with raw HTML disabled rather than trusting arbitrary HTML from the app's own history or a model's response.
Archive search follows the same layering, and it's intentionally simple. archiveRepo.searchDates(year, q) runs one SQL query — SELECT DISTINCT date FROM log_entries WHERE date LIKE '{year}-%' AND formatted_text LIKE '%{q}%' — scoped to the selected year, matching against the formatted (AI-cleaned) Markdown text. useArchiveSearch wraps that in a TanStack Query hook keyed on ['archive', 'search', year, q], only firing once you've typed something. The archive modal takes the resulting dates and highlights them on the year calendar; click one and it opens that day's log.
It's a substring match, not full-text or fuzzy search — no ranking, no tokenization, and it only searches log entries, not todos. Switching years re-runs the query. That's a deliberate tradeoff: it's fast, it's easy to reason about, and it covers the actual use case of "I remember roughly what I wrote, help me find the day." A smarter search engine is on the list of things that could get built later, but it hasn't earned its complexity yet.
Two months in
I've been using CapLog daily for two months now, and the sticky notes are gone. So is the handwritten journal, the OneNote tab, and the pile of open Notepad windows. Everything that used to live scattered across four places now lives in one feed I actually look back on, because looking back doesn't mean digging through a notebook or hunting for the right Notepad window.
The foundation is there: local storage, structured logs, task tracking, history and archive views, optional AI formatting, and export to a plain Markdown file. What's left is polish, not new scope — small improvements that make the daily habit smoother, not new features that make the app bigger.
Try it, or steal the idea
CapLog is open source: github.com/rbipin/caplog. If you're juggling the same scattered setup — a notes app here, a todo app there, a journal you keep meaning to open — clone it and see if one input box is enough for you too. And if it isn't quite right for how you work, the architecture is small enough to fork and bend into your own shape: layered frontend, local SQLite, no backend to fight with.