Skip to content

About

Node Wright: a framework-agnostic node-graph engine (protocol, store, semantics, runtime, layout, editor controller) with official Vue 3 and React adapters.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

English · 简体中文

Node Wright: a framework-agnostic node-graph engine with official Vue 3 and React adapters

CI Version 0.1.0-beta.3 MIT license TypeScript strict Vue 3.5+ React 18.3 / 19

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.

The playground in its dark theme: the AI image workflow on a full-screen canvas, with the scenario list at the top left, the toolbar at the top, the run results and execution trace on the right and the minimap at the bottom right

Dark is the default look; compare the light theme screenshot.

Demo: drag the preview node back, connect the image URL to its input, press Run until the preview shows the generated image, then drag the visible area in the minimap to pan the canvas

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.

The exec flow scenario in the dark theme: exec and data edges are told apart, node headers show their category colour and a success badge The same exec flow scenario in the light theme The phone layout: a top bar with the scenarios, a compact toolbar and the run panel as a bottom drawer
Exec flow · dark Exec flow · light Phone · bottom drawer

Features

🧠 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 protocol
GraphSnapshot 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.

Architecture

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
Loading

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/).

Quick Start

Installation

# 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-dom

Requirements: 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: {},
  }
}

Vue 3

<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>

React

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.

Headless runtime

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 }

Packages

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.

Live demo

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.

Documentation

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

Project status

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/view and the contract tests).

Contributing

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.

License

MIT

About

Node Wright: a framework-agnostic node-graph engine (protocol, store, semantics, runtime, layout, editor controller) with official Vue 3 and React adapters.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages