DRAFT: Nodepad Outliner [Work in Progress]

02 Jun 2026 • 3 min read

A powerful, hierarchical outliner application designed for creating and managing nested lists with ease. Inspired by Dynalist and Workflowy.

Nodepad is a keyboard-first, deeply hierarchical outliner application designed for creating and managing nested lists with ease. It allows developers and productivity enthusiasts to structure complex ideas, logs, and checklists in a simple, responsive outline interface.

[TBD] Some app ux-paths need to be reworked, next steps is to stabilize and deploy on nodepad.lex1001.cc.

  • Sentry logging
  • NodeLine buttons when editing - ok, cancel, drag&drop tip
  • Screenshots aren’t relevant, change here.
  • DemoUsers Isolation to prevent spam and abuse
  • Test prod usecases
  • Keymode luminate and hide/show

Screenshots


Technical Architecture

Nodepad is built with separation of concerns at its core, combining a robust relational schema with high-performance tree traversal.

1. Hierarchical Data Model (ltree)

To support deeply nested trees without suffering from the N+1 query problem or slow recursive CTE queries, Nodepad uses PostgreSQL’s native ltree extension.

  • Hierarchy Representation: Each node maintains both a parent_id foreign key and a materialized path (e.g., root.child1.child2).
  • Path Calculation: Handled cleanly in the backend service layer (backend/app/services/nodes.py) without polluting the raw model classes.

2. Custom Reordering (Fractional Indexing)

Nodes can be dragged, indented, or outdented dynamically.

  • Ordering: Handled via fractional indexing (decimal numbers, saved as Numeric(30, 15) in PostgreSQL to prevent precision loss).
  • Subtree Stability: During complex subtree movements, the backend uses a Longest Increasing Subsequence (LIS) algorithm (backend/app/services/lists.py). This minimizes database write operations by identifying the minimum number of nodes that actually need to have their positions updated.
  • Maintenance: A custom background indexer utility periodically resets positions to integers (multiples of 1000) to keep precision boundaries stable.

3. Frontend & State Boundary

  • Client State: Built on React 19 and TypeScript, powered by Zustand for state management and TanStack Router for routing.
  • Optimistic UI Updates: The frontend predicts reordering success and updates the client state immediately for an instantaneous, zero-lag feel.
  • Design System: Decoupled atomic UI components built with Tailwind CSS 4 and accessible Radix UI primitives.

Keyboard-First Outlining

Nodepad is built for keyboard navigation. Below is the list of shortcuts available on the outline editing screen:

ShortcutAction
EnterSave current node and finish editing
Shift + EnterCreate a new child node under current
TabIndent node (move right in hierarchy)
Shift + TabOutdent node (move left in hierarchy)
↑ / ↓ ArrowsNavigate seamlessly between nodes
BackspaceDelete node (when empty)
Ctrl + ZUndo last node edit or delete
EscapeCancel editing

Development Log & Next Milestones

Upcoming Features & Research Items

  • Keymode / Edit Mode: Introducing a physical keyboard mode indicator on the sidebar and configuring navigation via Shift + Arrows to allow quick keyboard actions without triggering input fields.
  • Tab Behavior: Improving indent/outdent UX so pressing Tab in edit mode begins moving the unsaved node without forcing the user to finish text input.
  • Encryption: Investigating server-side encryption for secure cloud list storage.
  • Performance: Setting up mock load-testing scripts for scale validation.
graph TD
    User([User Keyboard/UI Input]) -->|Optimistic Update| Store[Zustand Store]
    Store -->|API Request| API[FastAPI API Boundary]
    API -->|Domain Logic| Service[Service Layer - Path/LIS]
    Service -->|Database Operation| DB[(PostgreSQL ltree / Decimal Index)]
  

Start searching

Enter keywords to search articles.