System Overview
Lapis Notes is a layered Svelte application that reproduces a large part of the Obsidian runtime model
across shared web and desktop hosts. The current source tree is browser-first, and the approved product
targets are a web/PWA host and an Electron desktop host. The key design choice is that the workspace app
does not own most domain behavior; it mounts the renderer shell, creates the root App instance, and
delegates to runtime services and plugins.
The decision to adopt Electron as the first-party native desktop shell is recorded in ADR-003: Electron-First Desktop Shell.
Layer Diagram
user input
→ host shell (web/PWA or Electron desktop)
→ @lapis-notes/workspace (renderer shell)
→ @lapis-notes/api (runtime kernel)
→ Vault, Workspace, Configuration, Commands, Metadata, Plugins
→ @lapis-notes/ui (design system)
→ packaged feature plugins (markdown, search, bases, ...)
→ community plugins from /.obsidian/plugins
The approved cross-runtime plugin direction is recorded in ADR-001: Plugin Runtime Rework (desktop runtime target superseded in part by ADR-003).
Layers
| Layer | Package | Role |
|---|---|---|
| Monorepo root | package.json, pnpm-workspace.yaml | Build orchestration. PNPM workspaces with pnpm 10.12.3. |
| Runtime kernel | packages/api | App model, workspace tree, storage abstractions, plugin lifecycle, commands, settings, metadata cache, editor/view infrastructure, event system, and compatibility surface. |
| Design system | packages/ui | Reusable Svelte components wrapping Bits UI, paneforge, svelte-sonner, and TanStack Table. Tailwind-styled. No domain logic. |
| Application shell | packages/workspace | Visible renderer shell. Boots the web/PWA host directly today and remains the shared renderer layer for both web and desktop hosts. |
| Feature plugins | packages/plugins/* | Markdown editing (including inline list callouts), SQLite/AppDatabase-backed full-text search, structured data views (Bases/PEaQL), grammar checking (Harper WASM). |
| Desktop shell | packages/desktop-electron | First-party Electron desktop host. Owns app lifecycle, native window behaviour, IPC command handlers, and desktop-only runtime adapters. |
Technology Stack
| Concern | Technology |
|---|---|
| UI framework | Svelte 5 (runes: $state, $effect, $derived) |
| Language | TypeScript |
| Build | Vite |
| Styling | Tailwind CSS 4 with oklch color system |
| Editor | CodeMirror 6 |
| Package manager | pnpm 10.12.3 (workspace protocol) |
| VCS | Jujutsu (colocated with Git) |
Architectural Principles
-
App owns services. The
Appclass is the single root that constructs and holds the workspace, vault, plugin manager, commands, configuration, metadata cache, and all registries. -
Plugins are first-class. Built-in features and community plugins use the same
Pluginbase class, runtime states, andPluginManager. Core plugins are registered before discovery, then activated through the same manager as community plugins. -
File-first data flow. Storage updates propagate into metadata indexing, then into higher-level features like search and views. The vault is the source of truth.
-
Event-driven. Almost all classes extend
EventDispatcher(wrapping EventEmitter3). Changes propagate via typed events rather than direct mutation observers. -
Adapter-driven storage. OPFS is the default for new browser-local vaults. File System Access API covers user-selected real folders in web runtimes. Native hosts can add adapters without rewriting the runtime kernel.
-
Thin shells. The workspace app is composition code. Host shells stage the runtime, render the layout, and delegate domain behavior to the API layer and plugins.
-
Obsidian compatibility. The API surface intentionally mirrors Obsidian’s plugin API.
compat.ts, parity tests, and themomentshim maintain upstream compatibility. Community plugins canrequire('obsidian')and get@lapis-notes/api.