
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
A Vue 3 component library for building visual node-based graph editors with drag-and-drop functionality.
A Vue 3 component library for building visual node-based graph editors with drag-and-drop functionality.
npm install vueweave
# or
yarn add vueweave
First, import the VueWeave styles in your application entry point (e.g., main.ts):
import "vueweave/style.css";
VueWeave works out of the box with zero configuration:
<template>
<GraphCanvasBase />
</template>
<script setup lang="ts">
import { onMounted } from "vue";
import { useFlowStore, GraphCanvasBase } from "vueweave";
const flowStore = useFlowStore();
onMounted(() => {
flowStore.initData(
[
{ type: "node", nodeId: "A", position: { x: 100, y: 100 }, data: { label: "Node A" } },
{ type: "node", nodeId: "B", position: { x: 400, y: 100 }, data: { label: "Node B" } },
],
[
{ type: "edge", source: { nodeId: "A", index: 0 }, target: { nodeId: "B", index: 0 } },
],
{}
);
});
</script>
GraphCanvasBase automatically renders:
data.label, data.type, or "Node" as body textVueWeave provides two main components: GraphCanvasBase and NodeBase.
<template>
<GraphCanvasBase
:nodes="nodes"
:edges="edges"
:node-records="nodeRecords"
:update-position="updateNodePosition"
:save-position="saveNodePosition"
:validate-connection="validateConnection"
>
<template #node="{ nodeData, nodeIndex }">
<NodeBase
:inputs="nodeData.inputs"
:outputs="nodeData.outputs"
@open-node-edit-menu="handleOpenMenu"
>
<template #header="{ nodeData }">
<div>{{ nodeData.name }}</div>
</template>
<template #body-main>
<!-- Your node content here -->
</template>
</NodeBase>
</template>
</GraphCanvasBase>
</template>
<script setup lang="ts">
import { GraphCanvasBase, NodeBase, useFlowStore } from 'vueweave';
const store = useFlowStore();
const nodes = store.nodes;
const edges = store.edges;
const nodeRecords = store.nodeRecords;
function updateNodePosition(index: number, position: any) {
store.updateNodePosition(index, position);
}
function saveNodePosition() {
store.savePosition();
}
function validateConnection(edge: any) {
// Your validation logic
return true;
}
function handleOpenMenu(event: MouseEvent) {
// Handle node menu opening
}
</script>
VueWeave includes a Pinia store for managing graph state:
import { useFlowStore } from 'vueweave';
const flowStore = useFlowStore();
// Access nodes and edges
const nodes = flowStore.nodes;
const edges = flowStore.edges;
// Initialize data
flowStore.initData(nodes, edges, extra);
// Add/remove nodes
flowStore.pushNode(node);
flowStore.deleteNode(nodeIndex);
// Add/remove edges
flowStore.pushEdge(edge);
flowStore.deleteEdge(edgeIndex);
// Update node position
flowStore.updateNodePosition(index, position);
flowStore.saveNodePositionData();
// Undo/Redo
flowStore.undo();
flowStore.redo();
const canUndo = flowStore.undoable;
const canRedo = flowStore.redoable;
VueWeave includes several examples demonstrating different features:
The Validation Example (/validation route) demonstrates custom edge connection validation with different node types:
Each node displays its validation rules and behavior directly in the node UI, making it easy for developers to understand how custom validation works.
// Custom validation function example
const validateConnection = (expectEdge: GUIEdgeData, existingEdges: GUIEdgeData[]): boolean => {
const sourceNode = store.nodes.find((n) => n.nodeId === expectEdge.source.nodeId);
const targetNode = store.nodes.find((n) => n.nodeId === expectEdge.target.nodeId);
// Rule 1: Single input nodes - only one connection total
if (targetNode.type === "singleInput") {
const allEdgesToThisNode = store.edges.filter((edge) => edge.target.nodeId === expectEdge.target.nodeId);
return allEdgesToThisNode.length === 0;
}
// Rule 2: Type matching
if (sourceNode.type === "typeA" || sourceNode.type === "typeB") {
if (targetNode.type !== "output" && sourceNode.type !== targetNode.type) {
return false; // Type mismatch
}
return true; // Multiple connections OK
}
return true;
};
The main canvas component for rendering the graph.
Props (all optional):
nodes: Array of node data (defaults to store)edges: Array of edge connections (defaults to store)nodeRecords: Record of node positions and metadata (defaults to store)updatePosition: Function to update node positions (defaults to store)savePosition: Function to save positions (defaults to store)validateConnection: Function to validate edge connections (defaults to store)nodeStyles: Node styling configuration (colors or functions)getNodeKey: Custom key function for node renderingSlots:
head: Content to render above the canvasnode: Node template (receives nodeData and nodeIndex)
Default Rendering:
When no #node slot is provided, GraphCanvasBase automatically renders:
nodeData.data.label, nodeData.type, or "Node" as body contentThe base component for individual nodes.
Props:
inputs: Array of input ports { name: string, key?: string }[]outputs: Array of output ports { name: string }[]Events:
openNodeEditMenu: Emitted when the node is clickedSlots:
header: Node header contentbody-head: Content at the top of the node bodybody-main: Main node body contentVueWeave provides flexible edge color customization:
<GraphCanvasBase
:node-styles="{
edgeColors: {
edge: '#ec4899', // pink-500 - normal edge
hover: '#8b5cf6', // violet-500 - on hover
notConnectable: '#ef4444' // red-500 - invalid connection
}
}"
/>
<script setup>
import { GraphCanvasBase, type NodeStyleOptions } from 'vueweave';
const nodeStyleOptions: NodeStyleOptions = {
edgeColors: {
edge: '#6366f1', // Default color
hover: '#818cf8', // Default hover color
notConnectable: '#f87171',
customColor: (context) => {
const { sourceNodeId, targetNodeId, isNewEdge, hasTarget, isConnectable } = context;
// New edge being drawn without target: gray
if (isNewEdge && !hasTarget) {
return { edge: '#9ca3af', hover: '#9ca3af' };
}
// New edge with invalid target: red
if (isNewEdge && !isConnectable) {
return { edge: '#f87171', hover: '#fca5a5' };
}
// Custom color for specific node pairs
if (sourceNodeId === 'input' && targetNodeId === 'process') {
return {
edge: '#10b981', // green-500
hover: '#34d399' // green-400
};
}
// Return undefined to use default colors
return undefined;
}
}
};
</script>
<template>
<GraphCanvasBase :node-styles="nodeStyleOptions" />
</template>
EdgeColorContext properties:
sourceNodeId: Source node IDsourceIndex: Source port indextargetNodeId: Target node ID (empty for new edges without target)targetIndex: Target port indexisConnectable: Whether the connection is validisNewEdge: true if edge is being drawn (not yet committed)hasTarget: true if hovering over a valid target portFeatures:
Examples:
/validation route for validation-based edge coloring/styled route for data-flow-based edge coloringVueWeave provides utility functions for styling nodes:
import {
nodeMainClass,
nodeHeaderClass,
nodeOutputClass,
nodeInputClass,
buttonColorVariants,
edgeColors
} from 'vueweave';
import type {
GUINodeData,
GUIEdgeData,
NodePosition,
InputOutputData
} from 'vueweave';
# Build the application
npm run build
# Build the package for distribution
npm run build:module
This will generate:
lib/package/.d.ts) in lib/package/lib/package/style.cssvueweave/
├── src/
│ ├── package/ # Package source code
│ │ ├── components/ # Vue components
│ │ ├── composable/ # Composables
│ │ ├── store/ # Pinia store
│ │ ├── utils/ # Utility functions
│ │ ├── index.ts # Main entry point
│ │ └── style.css # Styles
│ └── ... # Application code
├── lib/ # Build output
└── package.json
MIT
Contributions are welcome! Please feel free to submit a Pull Request.
FAQs
A Vue 3 component library for building visual node-based graph editors with drag-and-drop functionality.
We found that vueweave demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.