Table of Contents (9 sections)
For the past decade, personal productivity software has been dominated by centralized cloud services. Tools like Notion and Airtable popularized dynamic block editing, relational databases, and multi-view project management. However, this convenience comes with steep trade-offs: proprietary vendor lock-in, recurring monthly subscriptions, vulnerability to outages, and the reality that your private thoughts, research notes, and intellectual property reside on remote infrastructure.
Conversely, traditional local markdown tools like Obsidian and Logseq championed local data ownership and bidirectional link graphs, but historically struggled to provide native, high-performance relational databases (Kanban boards, Gantt timelines, custom formulas, and inline rollups) without fragile third-party community plugins.
When building Studus, we set out to eliminate this false dichotomy. We engineered a unified, local-first knowledge operating system that combines structured block editing and dynamic multi-view databases with a 2D physics knowledge graph—all delivered through a lightweight, cross-platform monorepo that runs on desktop, mobile, and web with zero mandatory cloud accounts.
Here is the architectural blueprint of how we designed, built, and optimized Studus.
1. The Local-First Philosophy & Design Invariants
Local-first software requires rethinking data flow and state management from the ground up:
- Data Sovereignty: The primary copy of all data lives on the user’s local device (IndexedDB in web contexts, native SQLite/filesystem storage on desktop).
- Offline-First Guarantee: Every feature—including node creation, database querying, full-text search, and graph rendering—must function seamlessly without network access.
- P2P Synchronization: Devices should synchronize directly over local Wi-Fi via cryptographic pairing rather than depending on centralized multi-tenant sync relays.
- Agentic Extensibility: AI agents should have first-class, programmatic access to inspect, mutate, and query the workspace through standardized protocols like Model Context Protocol (MCP).
2. Monorepo Architecture & Decoupled Boundaries
To maintain strict domain boundaries and avoid leaky abstractions, we structured Studus as a package-based monorepo:
studus/
├── packages/
│ ├── core/ # Headless domain kernel (Zero DOM/Browser dependencies)
│ └── ui/ # Reusable workspace shell, block editor, & database views
├── apps/
│ ├── desktop/ # macOS / Windows / Linux shell (Tauri v2 + Rust HTTP Sync)
│ ├── mobile/ # iOS / Android app (Capacitor + Camera QR Pairing)
│ └── web/ # Standalone browser client (Vite)
└── server/
└── mcp/ # Model Context Protocol stdio & WebSocket bridge
3. The Headless Domain Core (@studus/core)
The heart of Studus is @studus/core. To ensure absolute portability, it is compiled under lib: ["ES2022"] with zero browser or DOM dependencies. It can execute identically inside a browser Web Worker, a Node.js daemon, a native Rust sidecar, or a headless CLI.
Hierarchical Document Tree
Every page and nested block in Studus is represented as a node within a recursive tree. Unlike flat document models, this tree supports arbitrary nesting depth, sibling reordering, subtree cascades (e.g., recursive deletion and permission cascading), and cycle prevention:
export interface WorkspaceNode {
readonly id: string;
parentId: string | null;
type: 'document' | 'database' | 'block';
properties: Record<string, unknown>;
childrenIds: string[];
createdAt: number;
updatedAt: number;
}
Reversible History Transactions
Undo/redo cannot simply be a snapshot of previous JSON blobs; on multi-thousand-node workspaces, serializing entire trees exhausts memory and introduces GC stutter.
Instead, we built HistoryManager on an atomic transaction model. Every mutation emits a forward operation and an inverse operation:
export interface HistoryTransaction {
readonly id: string;
readonly timestamp: number;
readonly operations: TransactionOp[];
readonly inverseOperations: TransactionOp[];
}
Applying a transaction executes operations; rolling back executes inverseOperations in reverse order. This guarantees $O(1)$ memory consumption per edit and millisecond-grade undo/redo cycles.
Multi-View Query Engine
The query engine powers our relational databases across Table, Kanban, Gantt, and Calendar views. Following Single Responsibility principles, we decomposed the engine into strategy evaluators:
- Multi-Column Filtering: Composable predicate trees supporting nested
AND/ORlogic. - Deterministic Sorting: Multi-column sorting with tie-breaker strategies.
- Swimlane Grouping: Partitioning nodes by single-select, multi-select, or dates.
- 15 Statistical Aggregations: Real-time evaluation of
sum,average,median,min,max,empty,filled, and date distributions.
4. Sliced State Store & Eliminating Split-Brain Renders
State management in large-scale productivity apps is prone to split-brain states—where the document tree says a node exists, but the database view or sidebar fails to reflect it.
To solve this, we centralized all domain logic in a typed Zustand store decomposed into modular domain slices:
treeSlice: Document and block hierarchy mutations.databaseSlice: Schema definitions, views, filters, and cell edits.searchSlice: Inverted backlink index and in-memory full-text search.uiSlice: Modal states, active selections, and drag-and-drop handles.
Each slice manages its own domain invariants while sharing a unified dispatch bus, preventing race conditions during rapid user input.
5. The Presentation Layer (@studus/ui)
The UI layer consumes @studus/core headlessly:
Notion-Grade Block Editor
Users expect fluid keyboard-driven interaction:
- Slash Commands (
/): Instantly invoke headings, lists, quotes, callouts, and custom database blocks. - Markdown Autocomplete: Typing
#,-, or[]immediately transforms the current line into formatted nodes. - Floating Toolbar & Gutter Handles: Draggable
⋮⋮handles enable frictionless block reordering via@dnd-kit.
Interactive D3-Force Knowledge Graph
Bidirectional links ([[Page Title]]) are indexed in an $O(1)$ reverse lookup map. To visualize complex knowledge clusters, we built a hardware-accelerated 2D canvas driven by a D3-force simulation.
By separating the physics tick calculations from React’s reconciliation cycle using custom state-machine hooks, the graph maintains 60 FPS even when navigating interconnected graphs with thousands of nodes.
6. Escaping the Electron Trap: Tauri v2 & Embedded Rust
Most modern desktop apps (Slack, Notion, Discord) bundle a complete Chromium runtime and Node.js instance via Electron. This architecture carries severe penalties:
- Idle Memory Bloat: 400–600 MB of RAM per window.
- Battery Drain: Constant background Chromium thread scheduling.
- Sluggish Startup: Multi-second cold-boot latency.
With Studus, we chose Tauri v2. Tauri replaces Chromium with the operating system’s native webview (WebKit on macOS, WebView2 on Windows) and uses Rust for native system logic:
┌─────────────────────────────────────────────────────────┐
│ Tauri v2 Window │
│ Native OS Webview (WebKit/WebView2) — ~15 MB RAM │
├─────────────────────────────────────────────────────────┤
│ Native Rust Backend │
│ • Multithreaded HTTP Sync Server (Port 42000) │
│ • Native File System I/O & SQLite │
│ • Local Cryptographic Key Storage │
└─────────────────────────────────────────────────────────┘
Results
- Memory Footprint: Slashed idle desktop RAM usage to ~15 MB—over a 95% reduction compared to typical Electron apps.
- Instant Cold Starts: The app window renders in under 250ms.
7. Local P2P Synchronization Without Cloud Relays
To synchronize between desktop and mobile without central cloud servers, the desktop app spins up an embedded, multithreaded native Rust HTTP server on port 42000.
When pairing a mobile device:
- QR Code Generation: The desktop displays a pairing QR code encoding its local IP address, port, and a temporary cryptographic PIN.
- Camera Scan: The Capacitor mobile app scans the QR code and establishes an encrypted mutual TLS/PIN-authenticated session over the local Wi-Fi.
- Delta Reconciliation: Devices exchange version vectors using Last-Write-Wins (LWW) timestamped deltas, merging changes without conflicts.
If the user disconnects from Wi-Fi, both apps continue operating locally and merge automatically upon reconnection.
8. The Agentic Bridge: Model Context Protocol (MCP)
Modern software must be built for both humans and autonomous AI agents. Rather than forcing AI assistants to scrape web views or parse raw database dumps, we built a native Model Context Protocol (MCP) server into Studus:
- Stdio & WebSocket Interface (
ws://127.0.0.1:4000): Exposes typed tools directly to AI coding and productivity assistants. - Granular Tooling: Agents can invoke tools such as
get_workspace_tree,create_document_node,query_database_view, andadd_backlinkprogrammatically. - Autonomous Organization: An AI assistant can review a user’s meeting notes, summarize action items, and automatically insert them into a Kanban database with zero manual copy-pasting.
9. Key Engineering Takeaways
- Decouple Business Logic from the DOM Early: Building
@studus/corewith zero browser dependencies unlocked instantaneous headless testing and made porting between Tauri, Capacitor, and Web trivial. - Avoid Snapshot-Based Undo: Transition-based inverse transaction engines protect application memory and ensure snappy user experiences on dense documents.
- Electron is Optional: Tauri v2 proves that modern desktop applications can achieve rich, modern web UIs while maintaining a tiny 15 MB native memory footprint.
- Local-First is the Future of Knowledge: By eliminating cloud lock-in, developers can give users what they truly want: speed, reliability, and absolute ownership of their digital minds.