circle-exclamation
KatanOS will not receive any updates at the moment, which is why I decided to make it open source.

sitemapArchitecture

Project structure, component hierarchy and data flow.

This document describes how KatanOS is structured and how data moves between UI, services, storage, and Electron.

Stack

  • Renderer: React 19 + TypeScript + Vite

  • Desktop shell: Electron 39

  • Styling: Tailwind CSS

  • Charts: Chart.js

  • AI SDK: @google/genai

  • Persistence: IndexedDB (katanos_storage) with localStorage fallback

Repository Layout

KatanOS/
  App.tsx
  index.tsx
  types.ts
  pages/
  components/
  services/
  electron/
  scripts/
  docs/

Process Model

KatanOS runs with two isolated contexts.

Electron Main (electron/main.cjs)

Responsibilities:

  • app/window lifecycle

  • splash + main window boot flow

  • IPC handlers (katanos:*)

  • safeStorage encryption/decryption bridge

  • filesystem operations for backup/export/import

  • logging (errors.log)

  • CSP and permission policy

  • Discord Rich Presence

Security-relevant BrowserWindow config:

  • contextIsolation: true

  • nodeIntegration: false

  • sandbox: true

  • devTools: false

Renderer (React app)

Responsibilities:

  • all module UI and interaction logic

  • domain CRUD through services/db.ts

  • settings orchestration (via components/Layout.tsx)

  • local-first state and persistence

  • notification and lock-screen flows

Renderer accesses privileged operations only through window.katanos preload APIs.

Entry Points

index.tsx

  • mounts <App /> into #root

  • loads styles/tailwind.css

  • forwards renderer errors to main process via window.katanos.logError

    • patched console.error

    • window.onerror

    • unhandledrejection

App.tsx

Central app orchestrator:

  • initializes storage (db.init())

  • restores current user (db.auth.getCurrentUser())

  • lazy-loads page modules

  • manages active page (activePage)

  • controls lock behavior (startup + inactivity)

  • handles exit prompt and close-confirm flow

  • emits Discord Rich Presence via window.katanos.setRichPresence

  • enables temporary dev mode via Konami code (3 minutes)

Navigation is state-driven, not route-driven.

  • HashRouter is present for Electron compatibility

  • page selection is controlled by activePage in App.tsx

  • Layout builds visible nav items from modulesService.getNavItems(user, lang)

Important implication:

  • module disablement hides navigation entries but does not enforce route-level hard blocking in App.tsx

UI Shell Composition

components/Layout.tsx

Primary authenticated shell containing:

  • sidebar/topbar

  • command palette (Ctrl/Cmd + K)

  • settings modal with tabs:

    • profile

    • personalization

    • preferences

    • categories

    • modules

    • backup

    • system

    • info

  • external-link confirmation modal

  • AI Scout panel

Page Modules (pages/)

  • Dashboard.tsx

  • Agenda.tsx

  • Todo.tsx

  • Finance.tsx

  • Contacts.tsx

  • Habits.tsx

  • Journal.tsx

  • Bookshelf.tsx

  • Vault.tsx

  • Games.tsx

  • Login.tsx (unauthenticated state)

Cross-Cutting Event Bus

KatanOS uses custom browser events for decoupled UI behavior.

Emitted events include:

  • katanos:notify

  • katanos:escape

  • katanos:openExitPrompt

  • katanos:katana

Consumers include:

  • NotificationSystem

  • module pages that close modals on escape

  • App exit prompt handlers

  • visual/audio easter egg logic

Startup and Shutdown Flow

Startup

  1. Electron creates splash window.

  2. Electron creates hidden main window.

  3. Renderer starts and initializes db.

  4. Renderer calls window.katanos.signalReady().

  5. Main window is shown after splash timing window.

Note:

  • signalReady currently does not shorten the splash minimum duration.

Shutdown

  1. Window close request is intercepted in main process.

  2. Renderer receives katanos:requestClose.

  3. If no user is logged in, close is confirmed immediately.

  4. If user exists, exit prompt opens in App.tsx.

  5. On confirmation, renderer triggers autosave and calls confirmClose.

Data Flow

Typical CRUD flow:

  1. User action in page/component.

  2. Call to db.* service.

  3. db serializes collection updates.

  4. storage.ts writes to IndexedDB cache store (kv) or fallback localStorage.

  5. UI reloads updated data.

Backup/export/import flow uses Electron bridge when filesystem access is needed.

Persistence Boundaries

  • canonical app data keys are in services/db.ts under chronos_*

  • auxiliary per-user UI keys also exist in localStorage (katanos_*)

  • autosave snapshots are forwarded to Electron via saveSnapshot

Electron autosave/export folder serialization currently stores a subset of domain files (events, todos, transactions, contacts, habits, journal) plus metadata/users.

Integrations

Runtime integrations used by modules/services:

  • Open-Meteo (forecast + geocoding)

  • Nominatim (reverse/place geocoding)

  • IP geolocation (ipapi.co)

  • Google Books API

  • Gemini APIs (places, finance insights, journal analysis, event parsing)

  • Wikipedia On This Day feed

Testing Structure

Notable test entry points:

  • services/vault.test.ts

  • components/layout/utils.test.ts

  • pages/dashboard/utils.test.ts

  • pages/finance/utils.test.ts

  • pages/finance/useFinanceCharts.test.ts

Run with:

Last updated

Was this helpful?