English · 简体中文
Live Demo · Docs · Quick Start · Changelog
Node Wright is a framework-agnostic node-graph engine with official Vue 3 and React adapters.
@node-wright/core is the low-level core: graph protocol, state, semantics, runtime, layout, debugging and a framework-agnostic editor controller. @node-wright/vue and @node-wright/react are the official adapters that render that controller with identical behavior, and @node-wright/presets provides the official preset nodes. The same graph can be edited in the browser, or validated and executed headless in Node.js or a Worker.
Dark is the default look; compare the light theme screenshot.
Drag a node → connect → run → see the image → navigate with the minimap. Captured from the playground that the live demo hosts (Vue build; there is also a React build). The playground UI is in Chinese.
![]() |
![]() |
![]() |
| Exec flow · dark | Exec flow · light | Phone · bottom drawer |
🧠 Framework-agnostic core@node-wright/core depends on no UI framework, and everything but the editor view runs without a DOM: save, validate and run graphs in the browser, Node.js or a Worker.
|
🧩 Official Vue 3 and React adapters Both adapters render one editor controller and pass one contract test suite for props, events, the ref API and the default DOM nodes. |
📐 Strict graph protocolGraphSnapshot is the only persisted format, external input enters through parseGraph(unknown) only, and every problem is a GraphDiagnostic.
|
🔌 Connection semantics Data-flow, exec-flow and hybrid rules: port types, capacity, cycles and required inputs, shared by interactive checks and whole-graph diagnostics. |
|
⚡ Execution runtime Execution plans, sequential and concurrent scheduling, variable scopes, function and subgraph calls, timeouts, idempotent retries, cancellation, breakpoints and stepping. |
🎨 Complete canvas interaction Pan and zoom, marquee selection, groups, connect and reconnect, copy and paste, undo and redo, shortcuts and context menus; DOM nodes, custom components or pure Canvas rendering. |
📦 Official preset nodes@node-wright/presets: 5 presets and 15 primitive nodes with DOM rendering config, semantic plugins, runtime definitions and layout strategies.
|
🧭 Auto layout Headless layered layout that only returns a position patch; the app decides whether to apply it and whether it enters the undo history. |
|
🌗 Dark and light themes Built-in dark and light palettes for the default nodes, edges, groups and grid, switched with theme.colorScheme; nodes carry a per-type accent and nodeStatus shows running, success and error.
|
🗺️ Minimap Optional overview of nodes, groups and the visible area; click, drag or use the arrow keys to pan the viewport. It only repaints when the graph or the overview range changes. |
flowchart BT
core["<b>@node-wright/core</b> · low-level core<br/>protocol · store · semantics · runtime<br/>layout · debug · view"]
presets["<b>@node-wright/presets</b> · official presets<br/>5 presets · 15 primitive nodes"] --> core
vue["<b>@node-wright/vue</b><br/>official Vue 3 adapter"] --> core
react["<b>@node-wright/react</b><br/>official React adapter"] --> core
headless["Node.js / Worker / server<br/>headless validation and execution"] -.-> core
All editor state and interaction (viewport, selection, dragging, connecting, clipboard, shortcuts, Canvas draw scheduling) lives in the controller of @node-wright/core/view; the Vue and React adapters only render its snapshots. Module dependency directions are enforced by tests. See Architecture (in Chinese, like the rest of docs/).
# Vue 3
npm install @node-wright/core @node-wright/presets @node-wright/vue vue
# React
npm install @node-wright/core @node-wright/presets @node-wright/react react react-domRequirements: Node.js >=20.19.0, ESM-only / ES2022, Vue ^3.5.13, React / React DOM ^18.3.0 || ^19.0.0. See support.
The Vue and React examples below share one graph and preset:
demo-graph.ts: a data source node wired to a preview node (click to expand)
import { NODE_WRIGHT_GRAPH_SCHEMA_VERSION, type GraphSnapshot } from '@node-wright/core/protocol'
import {
DATA_PREVIEW_NODE_TYPE,
DATA_SOURCE_NODE_TYPE,
createDataflowPreset,
} from '@node-wright/presets'
export const preset = createDataflowPreset()
export function createDemoGraph(): GraphSnapshot {
return {
schemaVersion: NODE_WRIGHT_GRAPH_SCHEMA_VERSION,
nodes: [
{ id: 'source', type: DATA_SOURCE_NODE_TYPE, x: 80, y: 120, data: { params: { value: 42 } } },
{ id: 'preview', type: DATA_PREVIEW_NODE_TYPE, x: 420, y: 120 },
],
edges: [
{
id: 'source-to-preview',
kind: 'data',
source: { nodeId: 'source', portId: 'value' },
target: { nodeId: 'preview', portId: 'value' },
},
],
groups: [],
meta: {},
}
}<script setup lang="ts">
import { ref } from 'vue'
import { NodeWright } from '@node-wright/vue'
import '@node-wright/vue/style.css'
import { createDemoGraph, preset } from './demo-graph'
const graph = ref(createDemoGraph())
</script>
<template>
<div style="height: 600px">
<NodeWright
v-model:graph="graph"
:node-definitions="preset.nodeDefinitions"
:node-types="preset.nodeTypes"
:plugins="preset.plugins"
:initial-viewport="preset.initialViewport"
/>
</div>
</template>import { useState } from 'react'
import { NodeWright } from '@node-wright/react'
import '@node-wright/react/style.css'
import { createDemoGraph, preset } from './demo-graph'
export function Editor() {
const [graph, setGraph] = useState(createDemoGraph)
return (
<div style={{ height: 600 }}>
<NodeWright
graph={graph}
onGraphChange={setGraph}
nodeDefinitions={preset.nodeDefinitions}
nodeTypes={preset.nodeTypes}
plugins={preset.plugins}
initialViewport={preset.initialViewport}
/>
</div>
)
}The editor root fills 100% of its parent, so give the parent a definite height. Keep the React preset at module level so renders do not rebuild the internal store. The component ref exposes the full NodeWrightApi; see getting started, the Vue adapter and the React adapter.
The same graph runs in Node.js without any UI:
import { NodeWrightRuntime } from '@node-wright/core/runtime'
import { createDemoGraph, preset } from './demo-graph'
const runtime = new NodeWrightRuntime({
graph: createDemoGraph(), // graphs from files or APIs go through parseGraph first
definitions: preset.nodeDefinitions,
runtimeDefinitions: preset.runtimeDefinitions,
})
const compiled = runtime.compile('preview') // start at preview and evaluate its data upstream
if (!compiled.plan) throw new Error(compiled.diagnostics[0]?.message)
const result = await runtime.run(compiled.plan)
console.log(result.status, result.nodeStates.preview?.inputValues) // 'success' { value: 42 }| Package | Role | Contents | Subpaths |
|---|---|---|---|
@node-wright/core |
Low-level core | Protocol, state, semantics, runtime, layout, debugging and the editor controller; runs headless | . (protocol + store)/protocol /store /semantics /runtime/layout /debug /view /view/style.css |
@node-wright/presets |
Official preset nodes | 5 presets and 15 primitive nodes | . /nodes/dataflow /nodes/execflow/nodes/function /nodes/subgraph |
@node-wright/vue |
Official Vue 3 adapter | Editor component | . /style.css |
@node-wright/react |
Official React adapter | Editor component and hook | . /style.css |
Every subpath export is listed in core-api.md and presets-api.md.
ruoyu-lab.github.io/node-wright hosts this repository's playground: the Vue build at the site root and the React build under /react/, with a switch at the bottom of the scenario list. It contains an AI image workflow and four primitive scenarios (data flow, exec flow, functions, subgraphs). The interface is a full-screen canvas with floating panels: scenario list, toolbar, run panel, minimap and zoom controls. It follows the system's dark or light preference and switches from the toolbar; on phones the run panel becomes a bottom drawer. The AI image scenario calls the public Pollinations image API, so it needs network access but no key; the primitive scenarios run entirely in the browser. To run it locally: npm install && npm run dev (React: npm run dev:react); see Playground.
Start at the documentation index. The documentation is written in Simplified Chinese; code samples and identifiers are in English. Common entry points: getting started · architecture · editor controller API · Vue adapter · React adapter · runtime API · writing business nodes · playground
0.1.0-beta.3 is a beta release: APIs may still change. See CHANGELOG.md.
What this release covers and what it does not
- Included: the low-level core (strict graph protocol, semantic rules, runtime, layout, debug helpers, the framework-agnostic editor controller and
NodeWrightApi), the official Vue 3 and React adapters, the official presets with 15 primitive nodes, and the Vue and React playgrounds. - Quality gates: strict TypeScript, type-aware ESLint, Prettier, coverage thresholds, real-tarball consumer tests (including Vue / React SSR and a React 18 consumer), three-engine E2E for both playground apps, and a 5,000-node performance budget.
- Not included yet: React 18 DOM component tests (covered by the packed consumer's type check and SSR); product features such as node search, persistence, collaboration, and entering or leaving subgraphs (no placeholder APIs); adapters for other UI frameworks (build one on
@node-wright/core/viewand the contract tests).
Issues and pull requests are welcome. Development workflow, commands, module boundaries and naming rules are in CONTRIBUTING.md (in Chinese); run npm run verify before submitting.




