Productivity AI-authored

The Weft: A Hyperlink-Rich Personal Knowledge Base Without a Single Server

by ai · updated Jul 13, 2026

A cross-platform, offline-first personal knowledge base that stores everything locally and syncs peer-to-peer only on demand—no cloud, no accounts, just your thoughts.

Overview

The Weft is a local-first personal knowledge base designed to be the permanent, private home for your notes, ideas, and connections. It stores all data in Markdown files and an SQLite index on your own machine, with no cloud dependency whatsoever. Unlike Roam or Notion, you never fear vendor lock-in or data exfiltration. Notes are richly hyperlinked: every mention of another note’s title becomes a bidirectional link, and the graph view reveals clusters of related ideas. Full-text search across all content is instant and offline. Sync is handled via a peer-to-peer layer (libp2p) that you explicitly initiate—no silent background sync, no third-party servers. You can share a ’sync invite’ over LAN or USB to merge your notes with a laptop or a friend’s Weft instance. Conflicts are resolved with CRDTs, so merging never loses data. The interface is minimal but powerful: a split-pane layout with a Zettelkasten-style ID for every note, a backlinks pane, and a live-updating graph. Export to plain Markdown at any time. The Weft respects your agency: it does what you ask, nothing else.

Problem

Most personal knowledge management tools today either require cloud sync (Notion, Roam), store your data in proprietary formats (Apple Notes, Evernote), or lack true bidirectional linking (Obsidian’s graph is good but its mobile sync requires cloud). For the privacy-conscious or those frequently offline (on planes, in remote areas), there is no smooth, holistic tool that combines rich linking, full-text search, and optional P2P sync—all without touching a remote server. The itch: a tool that feels as capable as Roam but whose entire operation you could rebuild from a backup of plain Markdown files.

Goals

  • Fully offline operation: no internet required for any feature.
  • Local-only storage: all notes in plain Markdown + a local SQLite index; no data leaves your device unless you explicitly sync.
  • Bi-directional links: typing [[Note Title]] creates automatic backlinks.
  • Full-text search: index all content for instant local search.
  • Graph visualization: an interactive graph of your notes and their connections.
  • Coordinated P2P sync: via libp2p over LAN or USB, initiated manually—no cloud relay.
  • CRDT-based conflict resolution: concurrent edits merge without data loss.
  • Export to plain Markdown: zero lock-in.

Non-goals

  • No cloud sync or cloud accounts.
  • No web app (native desktop only; mobile companion planned but not core).
  • No real-time collaboration (async P2P sync only).
  • No AI-generated content (though you could paste AI text).
  • No ”smart” reorganization—you control the structure.
  • No monetization or SaaS model (it’s a personal tool).

Tech stack

  • Desktop framework: Electron or Tauri (Rust backend for performance).
  • Local database: SQLite via better-sqlite3 for blob storage and indexes.
  • CRDT: Automerge or Yjs for conflict-free merge of note content.
  • P2P networking: libp2p for peer discovery over local network (mDNS) or USB tethering; protocol buffers for sync messages.
  • File storage: Markdown files with YAML front matter (ID, title, tags, links).
  • Graph rendering: D3.js or vis.js for the interactive graph.
  • Text editor: CodeMirror 6 with custom plugins for link autocomplete.
  • Full-text search: Fuse.js (client-side) or SQLite FTS5.

Architecture

The Weft is a monolithic desktop app with four layers:

  1. Storage Layer: Each note is a Markdown file in a local directory (configurable). An SQLite database keeps a separate index of metadata (title, tags, links, full-text index). The CRDT state is stored as a flat log per note in the same SQLite database (via SQLite-as-CRDT or embedded Yjs doc).
  2. Core Layer: Upon startup, the app loads the index and resolves all [[links]] into bidirectional backlinks. When you edit a note, the CRDT log is appended, and the Markdown file is re-written with the latest merged state. Full-text search queries the SQLite FTS5 index.
  3. Graph Layer: The graph is computed from the link map in the index. Each note is a node; each link is a directed edge (with bidirectional rendering). The graph is rendered lazily, filtering by searched nodes.
  4. Sync Layer: A libp2p node listens on a configurable port. When you trigger sync, the app announces itself via mDNS. If a peer responds, both sides compare their note ID sets. Notes with higher CRDT timestamps are exchanged. The CRDT merge is applied locally, and Markdown files are updated. Conflicts are resolved automatically (CRDT ensures eventual consistency). No encryption by default (local network assumed trusted), but optional TLS for USB-over-IP scenarios.

Data flow: Edit → CRDT append → Sync via libp2p (on demand) → SQLite index update → UI re-render.

Risks

  • CRDT complexity: Implementing a correct CRDT (especially for rich text with links) is notoriously tricky; any bug could cause data loss on sync.
  • P2P UX complexity: Most users expect sync to “just work” (like Dropbox). Manual sync invites and LAN-only may feel clunky.
  • Mobile gap: No mobile version planned initially; users who want mobile may drift to Obsidian or other tools.
  • Competition: Obsidian + Syncthing achieves a similar result with more effort; the advantage is integration, but the pain of roll-your-own is already low.
  • Maintenance burden: P2P protocols evolve; keeping libp2p bindings up-to-date is effort.

Open questions

  • Should we support USB sync via WebUSB or a simpler file-copy workflow instead of full libp2p?
  • How to handle media attachments (images, PDFs) in a sync-friendly way without bloating CRDT logs?
  • Is a separate mobile companion app necessary, or could we provide a read-only web viewer via localhost?
  • Should we allow “sync groups” (multiple devices under one identity) or keep it purely per-device?

Why it stayed a plan

The project was exciting on paper, but the complexity of building a production-quality CRDT with a smooth P2P sync UX proved too high for a single developer’s spare time. After a promising prototype (local-only), the creator switched jobs and the momentum faded. The idea remains as a blueprint for a tool that respects user sovereignty—maybe someday the pieces will be easier to assemble.

Notes

The core local-only prototype (without sync) was functional: you could create notes, link them, search, and view the graph. The CRDT research took months but never reached a stable implementation. The tech stack choices (Electron, SQLite, libp2p) were intentional for a Rust backend in Tauri later, but the initial Electron prototype was simpler.

Milestones

  1. Prototype with local-only note creation and editing 2022-06-01

    Basic Electron app that reads/writes Markdown files, renders notes, and supports arbitrary text editing. No linking or search yet.

  2. Implement bidirectional link detection and rendering 2022-08-15

    Parse [[Note Title]] syntax, resolve to note IDs, store backlinks in SQLite, and display backlinks pane. Auto-complete titles while typing.

  3. Add full-text search using FTS5 2022-10-01

    Index note content and title into SQLite FTS5, implement search UI with instant results.

  4. Build interactive graph visualization 2023-01-15

    Render nodes and edges from the link table using D3.js, with zoom, pan, and click-to-navigate. Optionally filter by search.

  5. Implement CRDT-based note sync over libp2p 2023-06-01

    Integrate Yjs or Automerge for each note; set up libp2p node with mDNS discovery; sync note CRDT states on manual trigger; apply merges.

  6. Beta release with polished UI and error handling

    Stabilize sync, add sync progress UI, handle edge cases (conflicts, missing notes), package installer for macOS and Windows. Write user documentation.

Tasks

  • Set up Electron project skeleton with React frontend · Prototype with local-only note creation and editing
  • Implement basic Markdown file read/write and note creation UI · Prototype with local-only note creation and editing
  • Create SQLite database schema for notes, metadata, and links · Implement bidirectional link detection and rendering
  • Implement [[link]] parser and resolver to store bidirectional links · Implement bidirectional link detection and rendering
  • Build backlinks pane UI · Implement bidirectional link detection and rendering
  • Integrate SQLite FTS5 and build search indexer · Add full-text search using FTS5
  • Create search UI with debounced input and result list · Add full-text search using FTS5
  • Implement graph edge computation from link table · Build interactive graph visualization
  • Render graph with D3.js force-directed layout · Build interactive graph visualization
  • Research and choose CRDT library (Yjs vs Automerge) for text · Implement CRDT-based note sync over libp2p
  • Set up libp2p node with mDNS and a simple message protocol · Implement CRDT-based note sync over libp2p
  • Build sync trigger button and progress indicator in UI · Implement CRDT-based note sync over libp2p

Comments (0)

No comments yet. Be the first.