XUDANU

30 Years of Hypertext Innovation

From Ted Nelson's 1963 vision, through Udanax Gold's C++ implementation, to a modern Rust engine with optimized transclusion queries.

Show & Tell · 2026
1 / 10
A Brief History of Xanadu
1963
Ted Nelson coins "hypertext" and begins the Xanadu project
Vision: documents that link to and include each other, with automatic attribution and micropayments
1960s
Nelson coins "micropayment" specifically for hypertext
Readers pay fractions of a cent; royalties flow to original authors automatically
1970s-80s
Xanadu design refined: transclusion, tumblers, enfilades
Core data structures invented: O-tree, H-tree, canopy, mappings
1989
Implementation in Smalltalk-80 at Autodesk
Mechanically translated to C++ (Objectworks for Smalltalk-80, v2.5)
1999
Udanax Gold open-sourced as C++ codebase
Complete front-end/back-end implementation ~200k LOC across 200+ files
~2005
Project goes dormant
All components ported but disconnected. Transclusion queries unimplemented. Dead code paths everywhere.
2025-26
Xudanu: Rust migration + optimization
Faithful port connected into a working system. Fingerprint-based indexing, canopy-filtered H-tree traversal, O(1) lazy transforms.
2 / 10
What Xanadu Got Right
"The HTML design was a pathetic compromise between ignorance and arrogance."
"The Web is a trivialization of the hypertext idea."— Ted Nelson (paraphrased from various talks)

Transclusion

Content is never copied — only referenced in place. When your paragraph appears in 10,000 documents, all 10,000 point to the same bytes. Updates propagate. Attribution is automatic.

Micropayments

When a reader accesses a document transcluding 5 authors, fractions of a cent flow to each. The cost() method tracks bytes, sharing, and ownership at element granularity.

Bidirectional Links

Every link goes both ways. You always know what links to your document. No more broken links. No more 404s. Every connection is tracked by the system.

17 Rules of Xanadu

The original specification required: no deletion (only new versions), visible connections between documents, automatic copyright tracking, no-typewriter model (non-sequential writing), and content-addressed storage. The Web implemented approximately zero of these.

3 / 10
Migrating with LLM Assistance
~200,000 lines of mechanically-translated Smalltalk → C++ → idiomatic Rust

The Challenges

  • Every .cxx file begins with "Output from Objectworks for Smalltalk-80, v2.5, 29 July 1989" — machine-translated, not human-written
  • Smalltalk idioms everywhere: fluid variables (dynamic scope), become: (object identity swap), deferred classes, sender-seeking message dispatch
  • All components ported but disconnected — transclusion queries were dead code, H-tree traversal never executed, canopy flags allocated but never checked
  • No test suite for transclusion behavior — had to derive correctness from first principles
  • Two-tier dual-write to separate indexes caused stale data accumulation

What LLMs Enabled

  • Read and understand 200+ interconnected C++ files with cross-references across Smalltalk, front-end, back-end, and storage layers
  • Trace data flow from BeGrandMap through BackfollowEngine to TransclusionIndex to identify the disconnection points
  • Generate idiomatic Rust for each component while preserving the original's algebraic invariants
  • Write property-based tests (1,643 total) covering 17 phases of incremental functionality
  • Debug performance by reading both the C++ and Rust simultaneously, comparing algorithms
4 / 10
The Three-Layer Architecture
Content identity enables all the optimizations. Same bytes = same fingerprint = same identity.
O-TreeBTree of RangeElements. Content-addressed via BLAKE3. 9 element types: Text, Data, Blob, Edition (nested), Label, PlaceHolder, IDHolder, Work, Overlay.
↓ fingerprint → TransclusionIndex
H-TreeVersion ancestry DAG. Each node (crum) carries fingerprint summaries of its subtree. Enables O(log n) "find all editions containing this content" without scanning.
↓ canopy flags prune branches
CanopyFlag-bit bitmap at each H-tree node. Endorsement types (Text=1, Link=2, Blob=4...) merged upward. If parent lacks your flag, skip entire subtree.
↓ BackfollowEngine orchestrates
Queryhash query → index lookup → H-tree walk (canopy-filtered) → collect matching works → results
5 / 10
The Performance Challenge
The Udanax team designed elegant data structures but left core queries unimplemented. We had to make them fast.
OperationNaive (C++ parity)Xudanu (optimized)How
Find works containing textO(W × L)O(U × A)Fingerprint HashMap intersection, no full scan
Find shared regions (diff)O(n × m)O(La + Lb)Fingerprint seed discovery + greedy claiming
Edition element listingO(n log n) every callO(1) after firstOnceLock cache shared via Arc on clone
Transclusion index lookupO(n) flat scanO(log n)H-tree canopy-filtered traversal
Position transform (shift)O(n) rewriteO(1)Lazy Dsp node wraps tree without traversal
Region highlightingO(r × t)O(r + t)Sorted regions, single pass
W = works, L = text length, U = unique fingerprints, A = avg works/fingerprint, n/m = doc lengths, r = regions, t = text

Key insight

BLAKE3 content fingerprints give us inverted indexes (fingerprint → works), intersection (shared content), and pruning (canopy flags) — all from the same hash. The O-tree's content-addressing IS the optimization.

6 / 10
Beyond Text: Compositional Data
Udanax Gold's RangeElement system allowed any mix of element types in any Edition. Editions can contain Editions. All the optimizations still apply.

9 Element Types

Text, Data, Blob, Edition (nested), Label, PlaceHolder, IDHolder, Work, Overlay

A single Edition can mix all types. Tables = Edition of Editions. Spreadsheets = Edition of Data. Templates = Edition of PlaceHolders.

Composition Operations

combine() merge · replace() override · copy() subset · transformedBy() reposition

Plus set algebra: union, intersect, minus, complement. All immutable. All work on any element type.

Optimizations Apply Universally

BLAKE3 fingerprints work on any RangeElement variant, not just Text. Canopy flags just allocate more bits for new types.

Dsp compose() handles multi-dimensional structures (CrossDsp) — same O(1) lazy transform.

Already ported: The entire compositional algebra is in the Rust crate — FeText, FeSet, XnRegion, Mapping, SharedMapping, Loaf (Leaf/Split/Dsp), OrglRoot, Bundle retrieval, Path navigation. The gap is UI + server protocol, not engine capability.

7 / 10
Micropayments: The Infrastructure Exists
pub struct StorageCost { total_bytes: u64, // Raw bytes unique_bytes: u64, // Bytes unique to this doc shared_bytes: u64, // Shared via transclusion share_count: u64, // How many docs share them method: CostMethod, // How to split } enum CostMethod { TotalShared, // Everyone pays full price ProrateShared, // Split equally (royalties) OmitShared, // Transcluded = free }

The accounting is per-element, not per-document. When Alice's paragraph appears in 10,000 documents via transclusion, the system knows she owns those bytes in all 10,000 contexts.

The Royalty Flow

  1. Alice writes content → server records ownership per element
  2. Bob transcludes Alice's paragraph → fingerprint match, shared_bytes incremented
  3. Reader accesses Bob's document → server calculates cost (ProrateShared)
  4. Micropayment splits → 60% to Alice, 35% to Bob, 5% server fee

Lightning Network via LDK

Millisatoshi precision, instant settlement, streaming "pay as you read". Rust-native library. Free to develop on testnet. The most Xanadu-aligned payment rail.

8 / 10
Live Demo

1. Create & Compare

Create two documents with shared text. Click Compare. See shared regions (amber), left-only (blue), right-only (orange). Bridge curves connect transcluded content across panes.

2. Edit in Context

Edit either pane while seeing highlights update live. Shared region positions shift as you type. The existing fingerprint-based regions are re-applied to the changing text in real time.

3. Save & Persist

Save either pane independently. Atomic work_save_and_release prevents races. The BackfollowEngine updates transclusion indexes. Subsequent compares reflect the changes.

1,643
Tests Passing
17
Phases Completed
0(n)
Worst-Case Query
200k
Lines Migrated
http://127.0.0.1:8090
9 / 10
What's Next

Near Term

  • Structured editing — expose Edition.combine/replace/copy to the UI for tables, outlines, nested documents
  • Age heatmap view — walk revision history, diff consecutive versions, color characters by when they were added
  • Reactive recorders — live transclusion notifications when new content matches your queries (SensorCanopy)
  • Federation — multi-node Xanadu servers sharing content with Last-Writer-Wins reconciliation

The Bigger Picture

  • Micropayment integration — Lightning Network (LDK) behind a feature flag. The accounting engine already exists.
  • Rust SDK — wrap the WebSocket protocol for programmatic access. Embed the engine directly for single-user tools.
  • Content marketplace — publisher dashboards, reader paywalls, royalty reports per transclusion event
  • WASM build — the core engine is no_std compatible. Run Xanadu in the browser.
"The Web is what it is because Tim Berners-Lee shipped something that worked. Xanadu never shipped. But the ideas — transclusion, bidirectional links, content identity, micropayments — were right. They were just 30 years early."
10 / 10