
13 July 2026
Why we built a React block editor with zero runtime dependencies
Open the package.json of most React rich text editors and you'll find a schema library, a state management layer, or both, sitting underneath the public API. noteloom's dependency list has exactly two entries: react and react-dom.
What that costs you today
A heavier dependency tree means a bigger bundle, more transitive-dependency surface area to patch when a CVE lands, and a schema you have to learn before you can read your own document format. None of that is a knock on those libraries — they solve harder generality problems than noteloom does. But most apps don't need that generality:
- You are not building a generic document framework for arbitrary schemas — you have a fixed set of block types you actually use.
- You want to read the stored document without a library-specific decoder.
- You want one version of react in the tree, not a state library pinned to whatever version the editor bundled.
The actual document model
Every noteloom document is a flat map of two arrays — blocks and runs — not a deeply nested tree. A block references its children by id; a run is a span of text with marks. That's the whole model:
{
"rootId": "root",
"blocks": [
{ "id": "root", "type": "page", "contentIds": ["h1", "p1"] },
{ "id": "h1", "type": "heading", "props": { "level": 1 } },
{ "id": "p1", "type": "paragraph" }
],
"runs": [
{ "id": "r1", "type": "text", "value": "Zero dependencies", "marks": {} },
{ "id": "r2", "type": "text", "value": "Just blocks and runs.", "marks": {} }
]
}Flat and normalized like this, it diffs cleanly, stores in a database column as-is, and round-trips straight back into a fresh editor with new EditorStore(json).
The tradeoff is explicit: noteloom covers the blocks and inline types most apps actually reach for, not an open-ended schema for every possible one.
When you'd want something else
If you need a battle-tested, production-proven real-time collaboration stack (Yjs-based operational transforms with years of hardening), or a fully pluggable schema for a document format you don't control, a larger framework still earns its weight — noteloom's own live collaboration (a custom CRDT over WebRTC) is real but explicitly experimental. noteloom is built for the much more common case: a single-user editor, or one that wants peer-to-peer collaboration without standing up a server, embedded in a React app, where every block type is something you defined and own.
The best dependency is the one you didn't have to add.
You can see the full block/run model in action in the Playground, or read the Architecture doc for how the store, registry, and history pieces fit together.
Read the Architecture docA real, live noteloom instance embedded inside the article. Want the full thing? Open the Playground.