@json-render/ink
v0.16.0
Published
Ink terminal renderer for @json-render/core. JSON becomes terminal UIs.
Readme
@json-render/ink
Ink terminal renderer for json-render. Turn JSON specs into interactive terminal UIs.
Installation
npm install @json-render/ink @json-render/core ink reactPeer dependencies: ink ^6.0.0 and react ^19.0.0.
Quick Start
1. Create a Catalog
import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/ink/schema";
import {
standardComponentDefinitions,
standardActionDefinitions,
} from "@json-render/ink/catalog";
export const catalog = defineCatalog(schema, {
components: standardComponentDefinitions,
actions: standardActionDefinitions,
});2. Render a Spec
import { render } from "ink";
import { createRenderer, standardComponents } from "@json-render/ink";
import { catalog } from "./catalog";
const InkRenderer = createRenderer(catalog, standardComponents);
const spec = {
root: "heading",
elements: {
heading: {
type: "Heading",
props: { text: "Hello from the terminal!", level: "h1" },
children: [],
},
},
};
render(<InkRenderer spec={spec} state={{}} />);Standard Components
Layout
| Component | Description |
|-----------|-------------|
| Box | Flexbox layout container (like a terminal <div>) |
| Text | Text output with optional styling (color, bold, italic, etc.) |
| Newline | Inserts one or more blank lines |
| Spacer | Flexible empty space that expands to fill available room |
Content
| Component | Description |
|-----------|-------------|
| Heading | Section heading (h1–h4) |
| Divider | Horizontal separator line with optional title |
| Badge | Small colored inline label for status |
| Spinner | Animated loading spinner with optional label |
| ProgressBar | Horizontal progress bar (0–1) |
| Sparkline | Inline sparkline chart using Unicode blocks |
| BarChart | Horizontal bar chart with labels and values |
| Table | Tabular data display with headers and rows |
| List | Bulleted or numbered list |
| ListItem | Structured list row with title, subtitle, leading/trailing |
| Card | Bordered container with optional title |
| KeyValue | Key-value pair display |
| Link | Clickable URL |
| StatusLine | Status message with colored icon |
| Markdown | Renders markdown-formatted text with terminal styling |
Interactive
| Component | Description |
|-----------|-------------|
| TextInput | Text input field with two-way binding |
| Select | Selection menu navigated with arrow keys |
| MultiSelect | Multi-selection with space to toggle, enter to confirm |
| ConfirmInput | Yes/No confirmation prompt |
| Tabs | Tab bar navigation with left/right arrow keys |
Generate AI Prompts
const systemPrompt = catalog.prompt({ system: "You are a terminal assistant." });Streaming
Use useUIStream to progressively render specs from JSONL patch streams:
import { useUIStream } from "@json-render/ink";
const { spec, send, isStreaming } = useUIStream({ api: "/api/generate" });Key Exports
| Export | Purpose |
|--------|---------|
| createRenderer | Create an all-in-one renderer component from a catalog |
| Renderer | Low-level spec renderer |
| JSONUIProvider | Combined provider (state, visibility, validation, actions, focus) |
| standardComponents | Pre-built component implementations for all standard components |
| schema | Ink element tree schema |
| useStateStore | Access state context (state, get, set, update) |
| useStateValue | Get single value from state |
| useBoundProp | Two-way binding for $bindState/$bindItem expressions |
| useUIStream | Stream specs from an API endpoint |
| createStateStore | Create a framework-agnostic in-memory StateStore |
Catalog Entry Points
| Entry Point | Exports |
|-------------|---------|
| @json-render/ink | Components, renderer, hooks, providers |
| @json-render/ink/schema | schema, InkSchema, InkSpec |
| @json-render/ink/catalog | standardComponentDefinitions, standardActionDefinitions |
| @json-render/ink/server | Server-safe re-exports (schema + catalog, no React dependency) |
