Z Zachary Lewis
Open source · npm · MIT

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.

npm install nlsr
grid · 72×22 · 60fps
writer → ↩ editor

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.

App.jsx
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.

← Back to all free tools