KABO
2026
A spatial interface for wandering through connected ideas.
The problem
Are.na is built around connections. You save a block into a channel, connect that channel to another, repeat over months or years — and something accumulates that's less like a folder and more like a way of thinking.
But you can never see it. The connections are there; they're just invisible. You navigate them one page at a time, linearly, like reading a book about a city instead of walking through one.
I wanted to see the shape of the thing.
A standard Are.na channel page next to the Kabo graph of the same channel.
Visualization of the same channel and block in Kabo
Design Challenge
What it's not
The easy version of this is an analytics dashboard. Block counts, connection depth, most-linked channels. I ruled that out early.
The people who'd want this aren't optimizing. They're researchers and thinkers who collect slowly and want a different way to encounter what they've built. Metrics would be noise.
No stats. No import/export. Every node links back to Are.na — this tool borrows a view, it doesn't capture data. And the graph accumulates: each click adds to it rather than replacing it. You build context by wandering. That's the whole model.
How it works
Paste an Are.na channel URL.
The app fetches its contents and renders a force-directed 3D graph in a dark field scattered with faint particles. Channels become white spheres, slightly luminous. Image blocks become floating planes with the actual image texture. Text blocks become small colored cubes. Connections are thin dark lines, present but unobtrusive.
Click a channel to load its contents.
New nodes appear, connected to what you opened. The graph grows outward. Click a block to load the channels it belongs to. A photograph you saved in one channel might also live in three others you've never visited. Those connections surface.
Hover brings a node to full opacity.
Channel spheres show bracket decorations [ ] — a quiet signal that this is a container you can open. Select opens a sidebar: channel name, block content, image preview, a link back to the original on Are.na, breadcrumb trail of where you've been.
First graph load.
Sidebar open with an image block selected.
Technical decisions
Node objects created once, never rebuilt.
This is the most important performance decision in the codebase. Updating a node's position means updating its transform matrix — not instantiating new geometry. Easy to get wrong when you're working reactively; every state change is a temptation to re-render from scratch.
Texture caching for image blocks.
Textures are keyed by block ID in a module-level Map. First visit uploads to the GPU; every subsequent visit returns the cached texture. Without this, revisiting any image block is visibly janky.
Controlled graph growth — by design.
Channel expansion returns up to 20 random blocks and 5 sub-channels. Block expansion returns up to 3 connected channels. These aren't API constraints; they're product constraints. A flood of 200 nodes on first click would break the thing the whole experience is built around.
Parallelized fetches, retry logic on the proxy layer.
Are.na's API has rate limits. Independent fetches run in parallel where possible; the proxy handles retries with backoff. Expansion feels snappy even when pulling from multiple endpoints.
Large graph — 40+ nodes, still responsive.
Graph expanding after a channel click — sparse, then growing, then settled.
What I'd build next
Shareable graph state.
Right now the graph lives only in your session. A URL that serializes the set of expanded channel IDs would let you show someone the shape of a research project — no database required.
Search within the graph.
Past ~30 nodes, finding something specific gets hard. A lightweight highlight-by-name would help. The constraint: it has to feel ambient, not modal. A search bar that breaks the spatial experience defeats the point.
Performance ceiling.
I haven't stress-tested 100+ nodes. Three.js should hold up; the force-directed layout is where I'd expect degradation at high density. Node clustering at zoom-out is the likely answer.
Mobile.
Orbit, zoom, WASD — none of it maps to touch. A touch-friendly variant would need to be a fundamentally different interface, probably 2D. I'd want to understand the actual use case before designing it.
What I learned
The hardest design work on this wasn't technical. It was saying no to noise — every default tooltip, every modal, every notification that wanted to exist. The interface should feel like a calm space for thinking. That's a constraint you have to actively defend, not one you get for free.
A well-explored graph.