The Thesis Neuron is a desktop knowledge workspace for Markdown and MDX. The starting principle is deliberately simple: a user's notes should remain ordinary files they can inspect, move, sync, version, or open without Neuron.
That makes local .md and .mdx files the source of truth. The application adds a fast workspace, live rendering, knowledge connections, plugins, and AI integrations around those files without turning the content into an opaque database.
Neuron in Use
Product Evidence

Split editor with live properties

Reading mode & MDX components

Notion-style .db databases

JSON Canvas boards
Architecture Built to Evolve The desktop shell is not one large application with filesystem, network, editor, and rendering concerns mixed together. Neuron separates them by privilege and responsibility.
The Electron main process owns filesystem access, repository scanning, settings persistence, and credential-safe network or AI requests. A lean preload bridge exposes a restricted, typed IPC contract. The React renderer stays focused on interaction, CodeMirror editing, Markdown syntax, and MDX component evaluation.
Local-first Process Architecture
System View
The trade-off is additional contracts and IPC coordination. I accepted that cost because the alternative couples interface code to host privileges, makes performance failures harder to isolate, and gives every future feature a path into the core.
File-Driven Surfaces A repository is just an ordinary folder, so the interesting question is what a file *becomes* when you open it. Neuron keeps a small surface registry that maps a file extension to the component that replaces the default Markdown editor — the file on disk stays plain text or plain JSON, but the editor it opens into is purpose-built.
A .canvas file opens as a JSON Canvas infinite whiteboard in the Obsidian-compatible format: undo/redo, multi-select, alignment, and Markdown cards with per-node styling. A .db file opens as a Notion-style typed database — colored select tags, filter and sort — backed by sql.js, stored as inspectable JSON with atomic writes and live reload when the file changes underneath it. A .nhtml file opens as an HTMX view: user-authored plain HTML plus bundled htmx, rendered inside a sandboxed webview against a capability-scoped, token-authenticated loopback API.
That last surface is the one I hardened most. The view server is loopback-only on an ephemeral port, hands each view a per-session token, and enforces default-deny capability manifests with glob path policies — so a local dashboard can read exactly what it declares and nothing else. It is Electron-free and carries its own test suite.
Architectural Pillar: The Zero-Trust Runtime The renderer is treated as an untrusted presentation surface. It has no direct Node.js capability, no environment-variable access, and no general filesystem API. Privileged integrations such as AI providers and network fetches stay in the main process, where credentials can remain outside the frontend bundle and outside ordinary IPC payloads.
Credential and Capability Boundary
Zero-trust Runtime
The preload bridge exposes only mapped operations with typed inputs and outputs. This does not make arbitrary content harmless, but it sharply reduces the capability available to a compromised renderer: an MDX snippet cannot invent a shell command or request an unmapped filesystem operation.
That micro-surface is a maintenance decision as much as a security decision. Every privileged action has one auditable handler and one explicit contract instead of being scattered through UI components.
Performance and Scale Without a Database Keeping plain files as the data tier avoids database lock-in and migration overhead, but it moves indexing responsibility into the application. A naive implementation would repeatedly scan every note for tags, graph edges, and wikilinks.
Neuron instead tracks file signatures and refreshes only changed nodes in an in-memory metadata cache. Parsing and workspace mapping run asynchronously away from the typing path. The renderer receives lightweight results rather than performing repository-wide work itself.
Incremental Workspace Index
Scale Without a Database
The trade-off is that the cache is disposable and must be reconstructed from files. That is intentional: the cache optimizes reads, but it never becomes a second source of truth. Corruption recovery is deletion and rebuild, not data migration.
Bug: Compounding Caret Displacement Symptom: clicking below a custom React widget placed the caret on the wrong text line, and the displacement accumulated farther down the document.
Root cause: widget margins collapsed outside their standard block wrappers. CodeMirror's height map measured each wrapper without the escaped vertical space, so its internal document geometry diverged from the DOM.
Debugging the Height Map
Before / After
Resolution: display: flow-root establishes a block formatting context around each widget and contains its margins. A second remeasurement after document fonts become ready removes smaller font-metric drift. The durable fix restored the layout contract instead of adding another timing observer.
Bug: Unclosed MDX Tag Parsing Crash Symptom: a self-closing component followed by prose on the same line, such as <Badge /> and trailing text, was treated as an opening block tag and crashed the parser while it searched for a closing tag.
Root cause: the first parser classified the entire line by its ending. It did not distinguish one valid leading component from the ordinary Markdown that followed it.
Defensive MDX Parsing
Decision Flow
Resolution: an anchored expression isolates the complete self-closing component first and captures the remainder separately. The component becomes a live widget; trailing prose returns to the standard Markdown stream. The parser now claims only the smallest syntax unit it can prove it owns.
Long-Term Sustainability Desktop applications accumulate debt quickly when integrations weave themselves through editor state. Neuron uses contribution registries so AI providers, workspace tools, MDX components, and distribution concerns depend on contracts rather than private document-engine internals.
Replacement-cost Map
Long-term Sustainability
This keeps replacement cost local. A model provider, renderer, or tool can change without rewriting the file model. Runtime and build dependencies are also kept at the boundary where they are used, making upgrades and security remediation less likely to destabilize the editor core.
From Project to Product A desktop workspace is only useful if people can install it. Version tags trigger GitHub Actions builds, and electron-builder produces native artifacts for Windows, macOS, and Linux. Releases use the repository-scoped GitHub token, so the delivery workflow does not require a hardcoded publishing credential.
Release Surface
v1.4.1
Windows
NSIS + portable + appx
macOS
DMG + ZIP / x64 + arm64
Linux
AppImage + Debian
3
Desktop platforms
1
Tagged release pipeline
The GitHub Pages download surface points users toward the latest release, while the release itself carries the platform-specific packages. What shipped as v1.0.0 is now under active development at v1.4.1, and every release has grown by adding a surface rather than rewriting the core.
What I Learned Neuron reinforced a pattern I keep seeing in systems work: difficult bugs often live at boundaries. The caret bug was a disagreement between CSS layout and CodeMirror's height model. The MDX crash was a disagreement between line-level parsing and component-level syntax. The distribution problem was a boundary between a static website and native desktop artifacts.
The best fixes made those boundaries explicit. Local files own the data. The main process owns privilege. IPC owns communication. The renderer owns interaction. Registries own extension. Release automation owns delivery.
That clarity is what lets Neuron grow without asking users to surrender control of their knowledge.