# tednaleid/limn architecture

> Architecture diagram of the GitHub repository tednaleid/limn, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-25). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/tednaleid/limn
- Repository: https://github.com/tednaleid/limn

## Overview

Limn is an offline-capable, keyboard-first mind-mapping app with web/PWA, desktop, and Obsidian entry points. The main workflow resolves or opens a document, edits its map through the shared core Editor, renders it, and persists or exports it. The graph includes documented editing, formatting, sharing, and storage capabilities; some subsystem wiring is omitted where the sampled source does not establish callers.

Main entry points: [`packages/web/src/App.tsx`](https://github.com/tednaleid/limn/blob/main/packages/web/src/App.tsx) (React app), [`packages/core/src/editor/Editor.ts`](https://github.com/tednaleid/limn/blob/main/packages/core/src/editor/Editor.ts) (Core Editor), [`packages/web/src/main.tsx`](https://github.com/tednaleid/limn/blob/main/packages/web/src/main.tsx) (Web bootstrap), [`packages/web/src/persistence/docRouting.ts`](https://github.com/tednaleid/limn/blob/main/packages/web/src/persistence/docRouting.ts) (Document routing)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_entry["App entry points"]
  node_web_entry["Web bootstrap<br/>[main.tsx]"]
  node_app["React app<br/>[App.tsx]"]
  node_obs_plugin["Obsidian plugin<br/>[main.ts]"]
end

subgraph group_editing["Mind map editing"]
  node_editor["Core Editor<br/>[Editor.ts]"]
  node_store[("Mind map store<br/>[MindMapStore.ts]")]
  node_dispatch["Key dispatch<br/>[dispatch.ts]"]
  node_navigation["Spatial navigation<br/>[navigation.ts]"]
  node_easymotion["EasyMotion jumps<br/>[easymotion.ts]"]
  node_drag["Drag and reparent<br/>[drag.ts]"]
  node_layout["Map layout<br/>[layout.ts]"]
  node_markdown["Inline markdown<br/>[inlineMarkdown.ts]"]
end

subgraph group_presentation["Rendering and interaction"]
  node_web_keyboard["Keyboard handler"]
  node_canvas["SVG mind map<br/>[MindMapCanvas.tsx]"]
  node_svg_export["SVG export<br/>[svg.ts]"]
end

subgraph group_storage["Documents and persistence"]
  node_routing["Document routing<br/>[docRouting.ts]"]
  node_web_persistence["Web persistence"]
  node_autosave["Auto-save"]
  node_serialization["File serialization<br/>[serialization.ts]"]
  node_share_url["Share URL codec<br/>[url.ts]"]
end

subgraph group_platforms["Platform integrations"]
  node_obs_view["Obsidian view<br/>[LimnView.ts]"]
  node_desktop["Desktop app<br/>[LimnApp.swift]"]
  node_desktop_bridge["WebView bridge"]
end

node_user(("User"))
node_indexeddb[("Browser IndexedDB")]
node_file_system[("Local files")]

node_user -->|"opens app"| node_web_entry
node_web_entry -->|"resolves document"| node_routing
node_web_entry -->|"mounts"| node_app
node_routing -->|"reads recent docs"| node_indexeddb
node_routing -->|"migrates legacy doc"| node_indexeddb
node_app -->|"creates and loads"| node_editor
node_app -->|"selects provider"| node_web_persistence
node_app -->|"starts auto-save"| node_autosave
node_autosave -->|"reads map data"| node_editor
node_autosave -->|"saves changes"| node_web_persistence
node_web_persistence -->|"stores documents"| node_indexeddb
node_web_keyboard -->|"dispatches keys"| node_dispatch
node_dispatch -->|"invokes edits"| node_editor
node_app -->|"renders view"| node_canvas
node_canvas -->|"reads map state"| node_editor
node_editor -->|"owns map state"| node_store
node_drag -->|"mutates positions"| node_store
node_drag -->|"centers children"| node_layout
node_obs_plugin -->|"registers view"| node_obs_view
node_user -->|"opens plugin"| node_obs_plugin
node_obs_view -->|"edits document"| node_editor
node_user -->|"opens app"| node_desktop
node_desktop -->|"bridges web view"| node_desktop_bridge
node_desktop -->|"opens and saves files"| node_file_system
node_app -->|"loads or saves format"| node_serialization
node_serialization -->|"encodes ZIP documents"| node_file_system
node_app -->|"exports map"| node_svg_export
node_app -.->|"creates share URL"| node_share_url

click node_web_entry "https://github.com/tednaleid/limn/blob/main/packages/web/src/main.tsx"
click node_routing "https://github.com/tednaleid/limn/blob/main/packages/web/src/persistence/docRouting.ts"
click node_app "https://github.com/tednaleid/limn/blob/main/packages/web/src/App.tsx"
click node_obs_plugin "https://github.com/tednaleid/limn/blob/main/packages/obsidian/src/main.ts"
click node_obs_view "https://github.com/tednaleid/limn/blob/main/packages/obsidian/src/LimnView.ts"
click node_editor "https://github.com/tednaleid/limn/blob/main/packages/core/src/editor/Editor.ts"
click node_store "https://github.com/tednaleid/limn/blob/main/packages/core/src/store/MindMapStore.ts"
click node_dispatch "https://github.com/tednaleid/limn/blob/main/packages/core/src/keybindings/dispatch.ts"
click node_navigation "https://github.com/tednaleid/limn/blob/main/packages/core/src/editor/navigation.ts"
click node_easymotion "https://github.com/tednaleid/limn/blob/main/packages/core/src/editor/easymotion.ts"
click node_drag "https://github.com/tednaleid/limn/blob/main/packages/core/src/editor/drag.ts"
click node_layout "https://github.com/tednaleid/limn/blob/main/packages/core/src/layout/layout.ts"
click node_markdown "https://github.com/tednaleid/limn/blob/main/packages/core/src/markdown/inlineMarkdown.ts"
click node_web_keyboard "https://github.com/tednaleid/limn/blob/main/packages/web/src/input/useKeyboardHandler.ts"
click node_canvas "https://github.com/tednaleid/limn/blob/main/packages/web/src/components/MindMapCanvas.tsx"
click node_web_persistence "https://github.com/tednaleid/limn/blob/main/packages/web/src/persistence/WebPersistenceProvider.ts"
click node_autosave "https://github.com/tednaleid/limn/blob/main/packages/core/src/persistence/AutoSaveController.ts"
click node_serialization "https://github.com/tednaleid/limn/blob/main/packages/core/src/serialization/serialization.ts"
click node_desktop "https://github.com/tednaleid/limn/blob/main/packages/desktop/Limn/LimnApp.swift"
click node_desktop_bridge "https://github.com/tednaleid/limn/blob/main/packages/desktop/Limn/WebViewBridge.swift"
click node_svg_export "https://github.com/tednaleid/limn/blob/main/packages/web/src/export/svg.ts"
click node_share_url "https://github.com/tednaleid/limn/blob/main/packages/core/src/export/url.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_web_entry,node_app,node_obs_plugin,node_user toneBlue
class node_editor,node_store,node_dispatch,node_navigation,node_easymotion,node_drag,node_layout,node_markdown,node_indexeddb,node_file_system toneAmber
class node_web_keyboard,node_canvas,node_svg_export toneMint
class node_routing,node_web_persistence,node_autosave,node_serialization,node_share_url toneRose
class node_obs_view,node_desktop,node_desktop_bridge toneIndigo
```

## Components

### App entry points

- [Web bootstrap](https://github.com/tednaleid/limn/blob/main/packages/web/src/main.tsx): `packages/web/src/main.tsx`
- [React app](https://github.com/tednaleid/limn/blob/main/packages/web/src/App.tsx): `packages/web/src/App.tsx`
- [Obsidian plugin](https://github.com/tednaleid/limn/blob/main/packages/obsidian/src/main.ts): `packages/obsidian/src/main.ts`

### Mind map editing

- [Core Editor](https://github.com/tednaleid/limn/blob/main/packages/core/src/editor/Editor.ts): `packages/core/src/editor/Editor.ts`
- [Mind map store](https://github.com/tednaleid/limn/blob/main/packages/core/src/store/MindMapStore.ts): `packages/core/src/store/MindMapStore.ts`
- [Key dispatch](https://github.com/tednaleid/limn/blob/main/packages/core/src/keybindings/dispatch.ts): `packages/core/src/keybindings/dispatch.ts`
- [Spatial navigation](https://github.com/tednaleid/limn/blob/main/packages/core/src/editor/navigation.ts): `packages/core/src/editor/navigation.ts`
- [EasyMotion jumps](https://github.com/tednaleid/limn/blob/main/packages/core/src/editor/easymotion.ts): `packages/core/src/editor/easymotion.ts`
- [Drag and reparent](https://github.com/tednaleid/limn/blob/main/packages/core/src/editor/drag.ts): `packages/core/src/editor/drag.ts`
- [Map layout](https://github.com/tednaleid/limn/blob/main/packages/core/src/layout/layout.ts): `packages/core/src/layout/layout.ts`
- [Inline markdown](https://github.com/tednaleid/limn/blob/main/packages/core/src/markdown/inlineMarkdown.ts): `packages/core/src/markdown/inlineMarkdown.ts`

### Rendering and interaction

- [Keyboard handler](https://github.com/tednaleid/limn/blob/main/packages/web/src/input/useKeyboardHandler.ts): `packages/web/src/input/useKeyboardHandler.ts`
- [SVG mind map](https://github.com/tednaleid/limn/blob/main/packages/web/src/components/MindMapCanvas.tsx): `packages/web/src/components/MindMapCanvas.tsx`
- [SVG export](https://github.com/tednaleid/limn/blob/main/packages/web/src/export/svg.ts): `packages/web/src/export/svg.ts`

### Documents and persistence

- [Document routing](https://github.com/tednaleid/limn/blob/main/packages/web/src/persistence/docRouting.ts): `packages/web/src/persistence/docRouting.ts`
- [Web persistence](https://github.com/tednaleid/limn/blob/main/packages/web/src/persistence/WebPersistenceProvider.ts): `packages/web/src/persistence/WebPersistenceProvider.ts`
- [Auto-save](https://github.com/tednaleid/limn/blob/main/packages/core/src/persistence/AutoSaveController.ts): `packages/core/src/persistence/AutoSaveController.ts`
- [File serialization](https://github.com/tednaleid/limn/blob/main/packages/core/src/serialization/serialization.ts): `packages/core/src/serialization/serialization.ts`
- [Share URL codec](https://github.com/tednaleid/limn/blob/main/packages/core/src/export/url.ts): `packages/core/src/export/url.ts`

### Platform integrations

- [Obsidian view](https://github.com/tednaleid/limn/blob/main/packages/obsidian/src/LimnView.ts): `packages/obsidian/src/LimnView.ts`
- [Desktop app](https://github.com/tednaleid/limn/blob/main/packages/desktop/Limn/LimnApp.swift): `packages/desktop/Limn/LimnApp.swift`
- [WebView bridge](https://github.com/tednaleid/limn/blob/main/packages/desktop/Limn/WebViewBridge.swift): `packages/desktop/Limn/WebViewBridge.swift`

### Other components

- **User**
- **Browser IndexedDB**
- **Local files**

## Connections

- User → Web bootstrap: opens app
- Web bootstrap → Document routing: resolves document
- Web bootstrap → React app: mounts
- Document routing → Browser IndexedDB: reads recent docs
- Document routing → Browser IndexedDB: migrates legacy doc
- React app → Core Editor: creates and loads
- React app → Web persistence: selects provider
- React app → Auto-save: starts auto-save
- Auto-save → Core Editor: reads map data
- Auto-save → Web persistence: saves changes
- Web persistence → Browser IndexedDB: stores documents
- Keyboard handler → Key dispatch: dispatches keys
- Key dispatch → Core Editor: invokes edits
- React app → SVG mind map: renders view
- SVG mind map → Core Editor: reads map state
- Core Editor → Mind map store: owns map state
- Drag and reparent → Mind map store: mutates positions
- Drag and reparent → Map layout: centers children
- Obsidian plugin → Obsidian view: registers view
- User → Obsidian plugin: opens plugin
- Obsidian view → Core Editor: edits document
- User → Desktop app: opens app
- Desktop app → WebView bridge: bridges web view
- Desktop app → Local files: opens and saves files
- React app → File serialization: loads or saves format
- File serialization → Local files: encodes ZIP documents
- React app → SVG export: exports map
- React app → Share URL codec: creates share URL
