Many agents, one canvas.
NLSR is a rendering engine for concurrent multi-agent text output on a fixed character grid. One agent streams forward while others revise earlier text — at the same time, without blocking.
The renderer streams text into a fixed grid while a second agent revises earlier phrases in real time▍
// both operate concurrently — neither blocks the other
Streaming UIs assume one writer. Agents aren't.
Most text renderers append, full stop. But multi-agent systems want to write and rewrite — a primary drafting forward while editors fix what's already on screen. NLSR makes that coordination a solved problem: a shared grid, flushed at 60fps, that every agent reads and writes without stepping on each other.
What it does
Forward streaming
A primary agent streams text into a fixed character-grid viewport, token by token.
Concurrent revision
Revision agents jump back and edit earlier phrases at the same time — neither blocks the other.
Shared grid coordination
The grid is the coordination mechanism — flushed at a steady 60fps for smooth output.
Stream adapters
Pipe ReadableStream, SSE/EventSource, or async iterables straight into the renderer.
Inter-agent messaging
A built-in message board lets agents post and read coordination messages.
Provider-agnostic
No LLM calls inside. Bring Claude, GPT, Gemini, LangGraph, or your own loop.
Quick start
Peer deps: react >= 18 and react-dom >= 18.
import { useRef, useEffect } from "react";
import { NLSRRenderer, createCoordinator } from "nlsr";
function App() {
const renderer = useRef(null);
const coordinator = useRef(null);
useEffect(() => {
coordinator.current = createCoordinator(renderer);
coordinator.current.registerAgent("writer", "primary");
coordinator.current.registerAgent("editor", "revision");
}, []);
const write = () => coordinator.current.write("writer", "Hello world. ");
const revise = () =>
coordinator.current.revise("editor", "Hello world", "Hello NLSR", "branding");
return <NLSRRenderer ref={renderer} cols={72} rows={22} />;
} Core API
A small surface — a coordinator, a renderer, and an optional stream adapter.
createCoordinator(rendererRef) Creates a coordinator that owns the text buffer and routes operations to the renderer. coordinator.write(agentId, text) Append text — primary agents only. coordinator.revise(agentId, old, new, reason) Replace a phrase — revision agents only. streamAdapter(coordinator, source, options) Pipe a streaming LLM response into write() calls. coordinator.messageBoard.post / read Inter-agent messaging between writer and revision agents. <NLSRRenderer cols rows /> The viewport component; exposes write() and revise() via ref. 🧩 Bring your own agents
NLSR never calls an LLM API. Wire Claude, GPT, Gemini, LangGraph, or a custom loop into the coordinator via write() and revise(). Full integration examples live in docs/integration.md.
Build multi-agent text UIs.
Free, MIT-licensed, and on npm. Install it and ship.