How FocusAnalyze is built
The stack, the architecture, and the productivity principles driving the product decisions
September 27, 2026
The shape of the system
FocusAnalyze isn't one app — it's four clients sharing one backend:
- Web (
focusanalyze-fe) — Next.js, the primary UI - Desktop (
focusanalyze-desktop) — Next.js + Tauri, for local focus tracking and offline support - Mobile (
focusanalyze-mobile) — React Native + Expo - Backend (
focusanalyze-mind) — Django + Django REST Framework, the API every client talks to
All three frontends consume a single REST client generated from the Django OpenAPI schema, rather than hand-written API types. When a serializer changes on the backend, the client regenerates — no manual type drift, no docs going stale, no "works locally, breaks in prod" surprises from a client and server disagreeing about a shape.
Underneath the API
- Postgres for the system of record.
- Celery for background work — reports, notifications, anything that shouldn't block a request.
- Keycloak for authentication, shared across every client.
- Weaviate as a long-term memory store, so the AI layer can learn preferences and patterns instead of starting cold every conversation.
- Google Calendar as the source of truth for events, synced both directions.
The AI assistant, FocusGPT, sits on top of this rather than beside it — it reads the same task/event/project models everything else does, and any action it proposes (scheduling a meeting, restructuring a plan) goes through a human-in-the-loop confirmation step before it commits. The AI is a collaborator with read/write access, not an opaque process making changes on your calendar without you seeing them first.
The productivity problem, translated into architecture
The product decisions map fairly directly onto specific failure modes I kept running into, in myself and in how most tools are built:
- Context switching overhead → tasks, events, and projects live in one system instead of three, because the cost of moving between tools is not just time, it's the reset of working memory each switch forces.
- Time blindness → the desktop app tracks actual focus time per app/project, because self-reported time estimates are unreliable in a specific, predictable direction — people underestimate how fragmented their day actually was.
- Planning friction → FocusGPT lets you create tasks and events conversationally, because the gap between "I know what I need to do" and "I've entered it into a system correctly" is where a lot of planning intent quietly dies.
- Calendar conflicts → the AI sees the full schedule before proposing anything, so double-booking is a check the system performs, not a thing you have to remember to do yourself.
- Context loss → long-term memory means the system doesn't ask you to re-explain your preferences every session.
None of this is exotic. It's mostly taking well-known failure points in how people actually work — not how project management tools assume people work — and building the architecture so the failure point isn't there anymore.
What I'd change
The generated-client approach and the shared backend across three platforms have paid for themselves many times over. The place I'm still iterating is the boundary between what the AI is allowed to do autonomously and what it should always surface for confirmation — that line moves as trust in the system's judgment (and mine, in how I've built it) increases.
LLM-friendly source: /posts/how-focusanalyze-is-built/md