{"id":11947,"library":"rete","title":"Rete.js: Visual Programming Framework","description":"Rete.js is a robust JavaScript framework for building visual programming interfaces and workflows, allowing developers to create node-based editors for dataflow, control flow, or mixed processing. It provides out-of-the-box solutions for visualization with various UI libraries (React, Vue, Angular, Svelte, Lit) and offers different types of engines for graph processing. The current stable version is 2.0.6, with recent minor updates addressing bug fixes and performance improvements. Rete.js v2 represents a significant architectural shift from v1, adopting a TypeScript-first approach, a flexible plugin system, and enhanced customization capabilities. Its modular ecosystem allows developers to pick and choose necessary packages, avoiding unnecessary dependencies and supporting custom builds.","status":"active","version":"2.0.6","language":"javascript","source_language":"en","source_url":"https://github.com/retejs/rete","tags":["javascript","dataflow","visual programming","node editor","rete","Rete.js","typescript"],"install":[{"cmd":"npm install rete","lang":"bash","label":"npm"},{"cmd":"yarn add rete","lang":"bash","label":"yarn"},{"cmd":"pnpm add rete","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Rete.js v2 is primarily designed with TypeScript and ESM in mind. While CJS is supported, modern projects should use ESM imports.","wrong":"const { NodeEditor } = require('rete')","symbol":"NodeEditor","correct":"import { NodeEditor } from 'rete'"},{"note":"Used with TypeScript to define the schema for nodes and connections, ensuring type inference across plugins. `ClassicPreset` provides common interfaces for building nodes and connections.","symbol":"GetSchemes","correct":"import { GetSchemes, ClassicPreset } from 'rete'"},{"note":"In Rete.js v2, `ClassicPreset` encapsulates the standard Node and Connection implementations for convenience and type safety. Direct instantiation of `Connection` from 'rete' is generally not the intended pattern for basic usage.","wrong":"import { Connection } from 'rete'; const connection = new Connection(...)","symbol":"Connection","correct":"import { ClassicPreset } from 'rete'; const connection = new ClassicPreset.Connection(sourceNode, 'portKey', targetNode, 'portKey')"}],"quickstart":{"code":"import { NodeEditor, GetSchemes, ClassicPreset } from 'rete';\nimport { AreaPlugin, AreaExtensions } from 'rete-area-plugin';\nimport { ConnectionPlugin } from 'rete-connection-plugin';\nimport { ReactPlugin, Presets, ReactArea2D } from 'rete-react-plugin';\nimport { createRoot } from 'react-dom/client';\n\ntype Schemes = GetSchemes<\n  ClassicPreset.Node,\n  ClassicPreset.Connection<ClassicPreset.Node, ClassicPreset.Node>\n>;\ntype AreaExtra = ReactArea2D<Schemes>;\n\nconst socket = new ClassicPreset.Socket('Number');\n\nclass MyNode extends ClassicPreset.Node {\n  width = 180;\n  height = 120;\n  constructor(name: string, numValue: number = 0) {\n    super(name);\n    this.addControl('value', new ClassicPreset.InputControl('number', { initialValue: numValue }));\n    this.addOutput('num', new ClassicPreset.Output(socket, 'Number'));\n  }\n}\n\nasync function createEditor(container: HTMLElement) {\n  const editor = new NodeEditor<Schemes>();\n  const area = new AreaPlugin<Schemes, AreaExtra>(container);\n  const connection = new ConnectionPlugin<Schemes, AreaExtra>();\n  const render = new ReactPlugin<Schemes, AreaExtra>();\n\n  AreaExtensions.zoomAt(area, editor.getNodes());\n  AreaExtensions.simpleNodesOrder(area);\n\n  render.addPreset(Presets.contextMenu.setup());\n  render.addPreset(Presets.classic.setup());\n\n  editor.use(area);\n  area.use(connection);\n  area.use(render);\n\n  const nodeA = new MyNode('A', 10);\n  const nodeB = new MyNode('B', 20);\n\n  await editor.addNode(nodeA);\n  await editor.addNode(nodeB);\n  await area.translate(nodeA.id, { x: 0, y: 0 });\n  await area.translate(nodeB.id, { x: 250, y: 0 });\n\n  const connectionAtoB = new ClassicPreset.Connection(nodeA, 'num', nodeB, 'num');\n  await editor.addConnection(connectionAtoB);\n\n  // Render the editor\n  const root = createRoot(container);\n  root.render(<ReactArea2D area={area} \n    // Pass extra props if needed\n  />);\n\n  console.log('Rete.js editor initialized with two nodes and a connection.');\n  return editor;\n}\n\n// To run this in a browser:\n// const container = document.getElementById('rete-container');\n// if (container) { createEditor(container); }","lang":"typescript","description":"This quickstart demonstrates how to set up a basic Rete.js editor with a custom node, two instances of that node, and a connection between them using the React renderer. It highlights the use of `NodeEditor`, `AreaPlugin`, `ConnectionPlugin`, and `ReactPlugin` with `ClassicPreset` for defining schemes and components."},"warnings":[{"fix":"Consult the official Rete.js v2 Migration guide and documentation. The `Component` abstraction from v1 is replaced with more flexible node creation. Plugins are now classes and connected differently.","message":"Rete.js v2 introduces significant architectural changes and breaking changes compared to v1, including a TypeScript-first design, a new plugin system, and a different approach to node and component creation. Migration requires substantial code refactoring.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Always treat arrays returned by `getNodes()` and `getConnections()` as immutable. If modifications are needed, perform them on a copied array or use the editor's API for adding/removing elements.","message":"Direct mutation of arrays returned by `editor.getNodes()` or `editor.getConnections()` might lead to unexpected behavior. These methods now return copies to prevent external interference with the editor's internal state.","severity":"gotcha","affected_versions":">=2.0.2"},{"fix":"For optimal development experience, use TypeScript (version 4.7 or higher is recommended) with Rete.js.","message":"Rete.js v2 relies heavily on TypeScript for improved developer experience and type safety. While usable with plain JavaScript, the developer experience (DX) will be significantly poorer due to the lack of type inference and stricter typing in the framework's design.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Optimize by connecting plugins only when needed, simplifying node rendering at low zoom levels (Level of Detail - LOD), and being mindful of expensive operations within node components. Implement `OnPush` change detection for Angular-based renderers where applicable.","message":"Performance issues can arise with a large number of nodes, especially in rendering-intensive scenarios. Synchronous operations or complex node rendering can block the main thread or cause low FPS.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Upgrade TypeScript to version 4.7 or higher. If not possible, use `@ts-ignore` for the `use` method as a temporary workaround.","cause":"Using an older TypeScript version (below 4.7) with Rete.js v2.","error":"Type instantiation is excessively deep and possibly infinite. ts(2589)"},{"fix":"Ensure `rete` and its necessary plugins are installed via `npm install rete rete-area-plugin rete-connection-plugin rete-react-plugin ...`. For CJS, ensure your bundler (Webpack, Rollup) or Node.js environment is configured to handle ESM imports correctly, or explicitly use `require()` if the package provides a CJS entry point. Modern Rete.js is ESM-first.","cause":"Incorrect package installation or module resolution issues in a CJS environment when expecting ESM.","error":"Error: Cannot find module 'rete' or Cannot resolve module 'rete'"},{"fix":"Wrap the editor/area initialization in a `setTimeout` with a small delay (e.g., 0ms or 10ms) to ensure the DOM has settled. Alternatively, manually call `area.resize()` after initialization if the container's dimensions are known.","cause":"The rendering container's dimensions might not be fully calculated or applied when the editor/area is initialized, especially in component lifecycle hooks (e.g., `ngAfterViewInit` in Angular).","error":"Editor does not render or appears blank until window resize."}],"ecosystem":"npm"}