npm.io
0.1.1 • Published yesterday

@samba425/diagramforge-react

Licence
MIT
Version
0.1.1
Deps
12
Size
2.6 MB
Vulns
0
Weekly
0

@samba425/diagramforge-react

Embeddable, offline-first diagram editor for React — a draw.io / Lucidchart alternative you can drop into any React 18+ or 19 app with a single component.

npm version License: MIT React

Live demo: samba425.github.io/Udraw
Source: github.com/samba425/Udraw


Why use this?

Need How DiagramForge helps
Add diagrams to your SaaS app Embed the full editor with <DiagramEditor /> — no iframe hacks
No vendor lock-in Open source (MIT), JSON document format, export SVG/PNG/PDF
Works offline 100% client-side rendering; optional AI backend is separate
Rich shape libraries Flowchart, UML, AWS, Azure, K8s, BPMN, org charts, and more
Developer-friendly TypeScript types, onChange callback, programmatic API for shapes/edges

Built with a custom SVG engine (not a wrapper around draw.io). Your users get pan/zoom, connectors, layers, grouping, undo/redo, templates, presentation mode, and import/export — inside your product.


Install

npm install @samba425/diagramforge-react

Peer dependencies: react and react-dom (^18 or ^19).


Quick start

import { DiagramEditor } from '@samba425/diagramforge-react';
import '@samba425/diagramforge-react/styles.css';

export function DiagramPage() {
  return (
    <DiagramEditor
      height="80vh"
      onChange={(project) => {
        console.log('Diagram updated:', project.name);
      }}
    />
  );
}

Required: Always import @samba425/diagramforge-react/styles.css. The editor uses Tailwind + CSS theme variables and will look broken without it.


<DiagramEditor /> props

Prop Type Default Description
initialProject Project empty diagram Starting document. Remount or change key to load a new doc.
onChange (project: Project) => void Called whenever the document changes. Use to save to your API or state.
readOnly boolean false View-only mode (pan and zoom).
apiBaseUrl string Backend URL for AI diagram generation.
themeMode 'light' | 'dark' | 'system' 'system' Color theme.
height CSS size '100%' Editor container height.
width CSS size '100%' Editor container width.
className string CSS class on the root wrapper.
style CSSProperties Inline styles on the root wrapper.
standalone boolean false Enables welcome dialog + IndexedDB autosave (first-party app mode).
features DiagramEditorFeatures see below Toggle panels and behaviour.
Feature flags (features)
Flag Embed default Description
ai true AI generation panel
presentation true F5 fullscreen slideshow
sourceEditor true JSON / YAML / Mermaid source view
minimap true Canvas minimap
welcome false Startup welcome / recovery dialog
persistence false Autosave to IndexedDB
<DiagramEditor
  features={{ ai: false, welcome: false, persistence: false }}
/>

Common integration patterns

Save to your backend
import { DiagramEditor, serializeProject, type Project } from '@samba425/diagramforge-react';
import '@samba425/diagramforge-react/styles.css';

async function saveDiagram(project: Project) {
  await fetch('/api/diagrams/123', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: serializeProject(project),
  });
}

export function Editor() {
  return <DiagramEditor onChange={saveDiagram} height="100vh" />;
}
Load existing diagram (controlled)
import { useState } from 'react';
import { DiagramEditor, parseProject, type Project } from '@samba425/diagramforge-react';
import '@samba425/diagramforge-react/styles.css';

function ControlledEditor({ json }: { json: string }) {
  const [project, setProject] = useState(() => parseProject(json));

  return (
    <DiagramEditor
      key={project.id}
      initialProject={project}
      onChange={setProject}
      height="80vh"
    />
  );
}
Read-only viewer
<DiagramEditor
  initialProject={loadedProject}
  readOnly
  features={{ ai: false, sourceEditor: false }}
  height="600px"
/>
Dark theme
<DiagramEditor themeMode="dark" height="80vh" />
Minimal embed (no AI, no autosave)
<DiagramEditor
  height="calc(100vh - 64px)"
  features={{ ai: false, welcome: false, persistence: false }}
  onChange={(p) => localStorage.setItem('diagram', JSON.stringify(p))}
/>

Build diagrams in code

Create shapes and edges programmatically, then pass as initialProject:

import {
  DiagramEditor,
  createProject,
  createPage,
  createShape,
  createEdge,
  createLayer,
} from '@samba425/diagramforge-react';
import '@samba425/diagramforge-react/styles.css';

const layer = createLayer('Main');
const page = createPage('Page 1', [layer.id]);
page.layers = [layer];

const boxA = createShape(
  { kind: 'rectangle', x: 80, y: 80, width: 160, height: 72, text: 'Start' },
  layer.id,
);
const boxB = createShape(
  { kind: 'rectangle', x: 320, y: 80, width: 160, height: 72, text: 'End' },
  layer.id,
);
page.shapes[boxA.id] = boxA;
page.shapes[boxB.id] = boxB;
page.order.push(boxA.id, boxB.id);

const edge = createEdge(
  { source: { shapeId: boxA.id }, target: { shapeId: boxB.id } },
  page.id,
);
page.edges[edge.id] = edge;
page.order.push(edge.id);

const project = createProject({ name: 'My flow', pages: [page] });

export function App() {
  return <DiagramEditor initialProject={project} height="80vh" />;
}

Export & share

import {
  exportSvg,
  exportPng,
  exportJson,
  buildShareUrl,
  loadTemplate,
} from '@samba425/diagramforge-react';

// From a Project object and active page:
await exportPng(project, pageId, { scale: 2 });
await exportSvg(project, pageId);
exportJson(project);

// Shareable URL (no server required):
const url = buildShareUrl(project, { viewOnly: false });

// Built-in templates: 'flowchart' | 'aws' | 'org-chart' | 'retro' | ...
const project = loadTemplate('flowchart');

Optional AI generation

The editor includes an AI panel. By default it uses a built-in offline heuristic generator. For LLM-powered diagrams, run the optional backend server and point the editor at it:

<DiagramEditor apiBaseUrl="https://your-api.example.com" />

Or set VITE_API_BASE_URL in your Vite app.


Exported API

// Component
export { DiagramEditor };
export type { DiagramEditorProps, DiagramEditorFeatures };

// Document types
export type { Project, Page, Layer, Shape, Edge, ToolId, ThemeMode, Camera, Point, Rect };

// File format
export { parseProject, serializeProject, FILE_SIGNATURE };

// Export
export { exportSvg, exportPng, exportPdf, exportJson, exportZip };

// Templates & share
export { DIAGRAM_TEMPLATES, loadTemplate };
export { encodeShareHash, decodeShareHash, buildShareUrl };

// Source editor (JSON / YAML / Mermaid)
export { projectToSourceText, applySourceToCanvas };

// Factories
export { createProject, createPage, createShape, createEdge, createLayer };

// Plugins (advanced)
export { pluginManager };
export type { Plugin };

Full TypeScript declarations ship in dist/index.d.ts.


What’s included in the editor

  • Infinite SVG canvas — pan, wheel zoom, grid, snap, smart guides
  • Shape libraries — Basic, Flowchart, UML, AWS, Azure, Network, Kubernetes, BPMN, Mind Map, Org Chart, Sticky Notes, Icons
  • Connectors — straight, orthogonal, curved, bezier; arrows, labels, animated lines
  • Grouping — group/ungroup, named groups, enter group (double-click), drag shapes into groups
  • Layers & pages — multi-page documents with layer visibility and lock
  • Undo / redo, clipboard, duplicate, align & distribute
  • Import / export — PNG, SVG, PDF, JSON, ZIP; import draw.io XML, Mermaid, PlantUML
  • Presentation mode (F5), minimap, in-diagram search
  • Themes — light / dark / system

Keyboard shortcuts (built-in)

Shortcut Action
V Select tool
H Pan tool
R / O / D Rectangle / Ellipse / Diamond
C Connector
Ctrl+G Group selection
Ctrl+Shift+G Ungroup
Ctrl+Z / Ctrl+Shift+Z Undo / Redo
Ctrl+C / Ctrl+V Copy / Paste
Delete Delete selection
F5 Presentation mode

See the full list in the app via ? or the keyboard shortcuts doc.


Framework notes

Vite

Works out of the box. Import the CSS as shown above.

Next.js (App Router)

Use a client component:

'use client';

import dynamic from 'next/dynamic';

const DiagramEditor = dynamic(
  () => import('@samba425/diagramforge-react').then((m) => m.DiagramEditor),
  { ssr: false },
);

import '@samba425/diagramforge-react/styles.css';
Create React App

Same as Quick start — import CSS in your root component or index.tsx.


Limitations (v0.1)

  • One editor instance per page — uses global Zustand stores; multiple <DiagramEditor /> on the same page is not yet supported.
  • Bundle size — full editor bundle (~1.6 MB ESM); code-split if needed.
  • SSR — client-only; disable SSR where you embed (see Next.js example).

Example app

Clone the repo and run the embed example:

git clone https://github.com/samba425/Udraw.git
cd Udraw/frontend && npm run build:lib
cd ../examples/embed-react && npm install && npm run dev
# → http://localhost:5199

Documentation

Topic Link
Embed guide docs/embed-package.md
Developer guide docs/developer-guide.md
Architecture docs/architecture.md
Plugin API docs/plugin-api.md
Backend API (AI) docs/backend-api.md

Contributing & support


Author

samba425 — built as an open-source alternative to proprietary diagram tools.

Keywords