Local-first personal knowledge management with spatial notes, relationships, and intelligent agents.
Local-first · User-owned data · No server required · Runs offline
Nexia-List is an open-source, local-first knowledge management tool inspired by Tinderbox. It provides:
-
Spatial Canvas - Arrange notes visually, see relationships at a glance
-
Linked Notes - First-class bidirectional links between ideas
-
Intelligent Agents (planned) - Persistent queries that continuously organize your knowledge
-
Prototype Inheritance (planned) - Notes inherit attributes from templates
-
Local-First - Your data lives on your device, in readable formats
-
Web-First - Runs in the browser; an optional desktop shell can wrap the same app
A note is a letter we send to our future self.
The Tinderbox Way
This is the animating purpose everything in Nexia-List serves — and, as the tool grows more powerful, aims to enlarge. Every capability exists to help that letter reach a richer future self: to resurface it at the right moment, connect it to your other letters, and let a decade of them be searched, computed over, and rediscovered. Power here is something to liberate the correspondence, never to constrain it.
Your knowledge is yours. Not in a cloud you don’t control. Not locked in a proprietary format. Not dependent on a company’s survival.
Nexia-List follows the local-first philosophy:
-
Data stored in human-readable formats (JSON)
-
Works offline by default
-
Optional sync is additive, never required
-
Export to open formats (HTML, Markdown, OPML — planned)
Nexia-List is local-first in design, web first in user interface. The primary target is the browser: the Rust core is compiled to WebAssembly so the real engine runs client-side, with no server required. A desktop shell is optional and external. You can use it anywhere you can access a browser (online, offline, mobile desktop, or whatever). Once you download it it is yours to run (so long as none of the dependencies get seized by BigTech). Download it and you have the file to keep, yourself, forever.
┌──────────────────────────────────────────────────────────┐
│ ReScript UI (TEA-style) │
│ Model / Msg / Update / View — hand-rolled TEA loop │
│ on @rescript/react; bundled by esbuild → web/dist/ │
└─────────────────────────┬────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ Browser (primary target) │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ Rust Core → WASM (wasm-bindgen) │ │
│ │ Notes · Backlinks · Search · JSON storage │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ Persistence: IndexedDB + file download/upload │
└─────────────────────────┬────────────────────────────────┘
│ optional
▼
┌──────────────────────────────────────────────────────────┐
│ Gossamer desktop shell (OPTIONAL, EXTERNAL) │
│ Requires a sibling checkout of hyperpolymath/gossamer; │
│ intentionally not built in this repo's CI │
└──────────────────────────────────────────────────────────┘| Layer | Technology | Purpose |
|---|---|---|
UI Framework |
ReScript 11 + hand-rolled TEA on |
Type-safe functional UI with The Elm Architecture pattern |
Core Engine |
Rust (serde, serde_json, uuid, chrono, thiserror) |
Note/Notebook model, backlinks reverse index, substring search, JSON storage |
Browser Bridge |
wasm-bindgen (wired) |
Compiles the Rust core to WASM so the browser runs the real engine; loaded at boot and covered by a CI contract test |
Tooling |
Deno 2 tasks + esbuild |
Package management, dev server, bundling — no npm/bun/yarn/pnpm CLIs |
Storage |
JSON via IndexedDB + file download/upload |
Local-first persistence in the browser |
Desktop (optional) |
Gossamer (external sibling checkout) |
Thin webview shell wrapping the same web bundle |
ReScript + TEA-style architecture gives us:
-
Exhaustive pattern matching (compiler catches missed states)
-
Pure update functions (easy testing, time-travel debugging)
-
Single source of truth (no stale UI bugs)
-
Type-safe message passing
Rust compiled to WASM gives us:
-
Memory safety without GC pauses
-
One core implementation shared by browser and any future shell
-
No type drift between "desktop core" and "web core"
These appear in older docs as if they existed — they do not, yet:
-
Graph engine via petgraph
-
Full-text search via tantivy (current search is substring matching)
-
Nickel schemas for configuration/validation
-
Service worker / offline PWA install
-
Mobile targets
-
A dedicated TEA library and URL router (the current TEA loop is hand-rolled;
rescript-teaandcadre-tea-routerwere removed as unused/unresolvable)
The larger direction — treating the notebook as live, homoiconic data that a real Lisp (LambdaDelta, λδ) can read, query, transform, and extend — is recorded in ADR-0003. The guiding constraint is that this power is opt-in and invisible by default: Nexia-List stays a Tinderbox-like tool you can use for life without ever seeing a parenthesis, while power users gain the full expressive reach of Lisp.
-
✓ Create, edit, delete notes
-
❏ Spatial canvas with drag-and-drop (pan/zoom and double-click create work; drag-and-drop pending)
-
✓ Bidirectional linking between notes (in core; UI surfacing in progress)
-
✓ Basic search
-
✓ Local file storage (JSON)
-
❏ Optional desktop shell (Gossamer, external)
nexia-list/
├── core/ # Rust — note/notebook engine + λδ substrate (5,344 LOC, 90 tests)
│ ├── Cargo.toml
│ └── src/
│ ├── lib.rs # Crate root
│ ├── note.rs # Note data model (serde)
│ ├── notebook.rs # CRUD, backlinks reverse index, substring search
│ ├── storage.rs # JSON save/load
│ └── wasm.rs # wasm-bindgen bridge for the browser
├── ui/ # ReScript — TEA-style app (~880 LOC)
│ ├── rescript.json
│ └── src/
│ ├── Main.res # Entry point
│ ├── Model.res # Application state
│ ├── Msg.res # Message type
│ ├── Types.res # Shared types
│ ├── Update.res # Message handling
│ ├── View.res # Rendering (list, editor, canvas)
│ └── bindings/
│ └── DomBindings.res
├── scripts/ # Deno build/dev scripts (esbuild bundling, dev server)
├── web/ # Browser entry (index.html, styles) + bundle output (dist/)
├── desktop/ # OPTIONAL Gossamer shell — requires external sibling
│ # checkout of hyperpolymath/gossamer; not built in CI
├── docs/ # ADRs, reports
└── tests/ # Cross-cutting tests# Clone the repository
git clone https://github.com/hyperpolymath/nexia-list.git
cd nexia-list
# Install dependencies
deno task setup
# Run development server (http://localhost:5173)
deno task dev
# Build for production (ReScript + web bundle)
deno task build
# Build the WASM core
deno task build:wasm
# Run tests (Rust core + UI)
deno task testContributions welcome! Please read our Contributing Guide first.
-
Local-first always - Never require network for core functionality
-
Web-first - The browser is the primary target; shells are additive
-
Type safety - Leverage ReScript’s type system fully
-
Performance - Keep UI responsive with 10,000+ notes
-
Simplicity - Resist feature creep, do fewer things well
MPL-2.0 for code, CC-BY-SA-4.0 for documentation. See LICENSE for details.
Your knowledge is yours. The code to manage it should be too.
-
Tinderbox - The inspiration for spatial note-taking
-
ReScript - Type-safe language compiling to JS
-
Gossamer - Lightweight webview shell with Zig FFI
-
hyperpolymath ecosystem
See TOPOLOGY.md for a visual architecture map and completion dashboard.
