Sunday, 12 July 2026

LightDraw.js: One Library for Dashboards, Automotive HMIs, Diagrams, and UI — Without the Dependency Bloat

Standard

If you've ever tried to ship a real-time dashboard inside an embedded WebView, or let an AI agent generate a live admin panel, you know the pain: React here, Chart.js there, D3 for one chart, a diagram library for topology, and suddenly your "simple HMI" is a 2 MB bundle that won't even run on Chromium 49 in a car infotainment stack.

LightDraw.js is a different bet. It's a zero-dependency, JSON-first 2D graphics engine for the browser — dashboards, automotive clusters, network diagrams, and form-style UI controls, all from one API. Canvas when you need speed. SVG when you need vectors. HTML when you need accessibility or legacy WebView support.

In this guide, I'll walk through what LightDraw actually is, how to get started in under five minutes, and five real-world use cases with code you can copy, tweak, and run today.

What Problem Does LightDraw Solve?

Building interactive 2D graphics in the browser usually means stacking tools:

Typical stackThe pain
React + Chart.js + D3 + diagram libHuge bundle, framework lock-in, four APIs to learn
Raw Canvas APINo scene graph, manual hit-testing, no animation timeline
Low-code / AI UI generatorsOutput is React/JSX — hard to embed in WebView or validate
Automotive HMI toolsExpensive, closed, or not web-native

LightDraw replaces that stack with one engine:

  • Retained-mode scene graph — add, move, and animate nodes; the renderer redraws efficiently
  • Three renderers — Canvas (performance), SVG (vectors), HTML (accessibility + old WebViews)
  • JSON scenes — load, validate, export; ideal for AI agents and config-driven UIs
  • Domain modules — dashboard widgets, automotive cluster, diagrams, UI components — same API
  • ES5 legacy build — ship to Chromium 49+ infotainment without a runtime transpiler

Bundle sizes (gzip): core ~26 KB, full bundle ~101 KB, dashboard plugin ~32 KB, automotive ~29 KB. You only load what you need.

Who Is This For?

✅ Great fit:

  • IoT / ops dashboards on factory tablets or NOC wall displays
  • Automotive digital cockpits fed by CAN or simulator data
  • AI-generated admin panels where the agent outputs JSON, not JSX
  • Network topology and architecture diagrams in docs or incident boards
  • Embedded control panels on Raspberry Pi kiosks — single HTML file, no npm on device

❌ Not the right tool:

  • Full SPA with routing and SSR — use React/Vue for the shell; embed LightDraw in a panel
  • 3D games — use Three.js or Babylon
  • Google Docs–class document editing
  • Native mobile UI — Swift/Kotlin territory

Step 1: Install LightDraw

Option A — npm (modern apps)

npm install lightdraw
import LightDraw from 'lightdraw';

const app = LightDraw.createApp('#app', {
  width: 800,
  height: 600,
  renderer: 'auto',  // canvas | svg | html
  background: '#1e293b'
});

Option B — CDN (no build step)

Perfect for embedded devices, kiosks, or quick prototypes:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lightdraw@1/dist/lightdraw.min.css">
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/lightdraw@1/dist/lightdraw.min.js"></script>
<script>
  const app = LightDraw.createApp('#app', { width: 800, height: 600, renderer: 'html' });
</script>

Expected output after Step 1: An empty canvas (or HTML surface) with your chosen background color. No errors in the console. You're ready to draw.

Step 2: Draw Your First Scene (JavaScript API)

LightDraw uses a retained-mode scene graph. You create nodes, add them to the stage, and the engine handles redraws, hit-testing, and animation.

const app = LightDraw.createApp('#app', {
  width: 800,
  height: 600,
  renderer: 'canvas',
  background: '#1e293b'
});

const circle = app.circle({
  x: 200,
  y: 200,
  radius: 50,
  fill: '#2563eb',
  draggable: true
});

app.add(circle);

circle.on('click', () => {
  circle.animate({
    scale: 1.5,
    duration: 300,
    easing: 'easeOutBounce'
  });
});

Output:

What you'll see: A blue circle on a dark slate background. Click it — it bounces to 1.5× scale. Drag it — it moves with your pointer. That's the scene graph and interaction layer working without you writing a single requestAnimationFrame loop by hand.

Step 3: Build UIs from JSON (The AI-Friendly Path)

This is where LightDraw diverges from most canvas libraries. Instead of imperative drawing calls, you can describe an entire UI as JSON and load it in one line:

app.loadJSON({
  type: 'group',
  children: [
    { type: 'thermometer', props: { value: 72, x: 24, y: 24 } },
    {
      type: 'lineChart',
      props: {
        data: [18, 22, 31, 28, 35],
        width: 400,
        height: 160,
        x: 24,
        y: 120
      }
    },
    { type: 'gauge', props: { value: 68, size: 110, x: 480, y: 40 } },
    {
      type: 'statusBar',
      props: {
        segments: ['Connected', 'MQTT', '1.2k msg/s'],
        x: 24,
        y: 300
      }
    }
  ]
});

Output:

What you'll see: A mini ops dashboard — thermometer at 72°, a line chart with five data points, a gauge at 68%, and a status bar showing connection info. No React. No Chart.js import. One JSON object.

To update live data:

const gauge = app.stage.findOne('gauge');
gauge.set('value', 85);
app.requestRender();

Step 4: Validate JSON Before Rendering (Critical for AI)

When an LLM generates your UI, you must validate before rendering. LightDraw ships schema docs and a built-in validator:

const scene = await fetch('/api/agent/scene.json').then(r => r.json());

const { valid, errors } = LightDraw.validateSceneJSON(scene);

if (!valid) {
  console.error('Scene validation failed:', errors);
  // Example error output:
  // ["Unknown type 'gague' — did you mean 'gauge'?"]
  return;
}

app.clear();
app.loadJSON(scene);
app.setUiTheme({ preset: 'slate', mode: 'dark' });

Expected output when valid: A themed dark UI renders immediately (see AI admin panel example below).

Expected output when invalid: valid: false and a human-readable errors array — no half-broken UI on screen.

The validation pipeline for AI:

User prompt → LLM + schema docs → scene JSON → validateSceneJSON → loadJSON → live UI

Step 5: Pick the Right Renderer

RendererBest forTrade-off
canvas60 FPS animations, 1000+ nodes, automotive clusterRaster — export as PNG
svgCrisp vectors, zoom-friendly diagramsDOM-heavy at very large node counts
htmlForm controls, accessibility, legacy WebViewsNot ideal for 5000-node particle systems
autoLet LightDraw pick based on contextGood default for prototyping

Benchmark snapshot (canvas renderer, 1000 nodes): render ~0.46 ms per frame — enough headroom for 60 FPS on mid-range hardware.


Real-World Use Cases (With Code and Screenshots)

Use Case 1: IoT / Factory Floor Dashboard

Scenario: A tablet on the factory floor shows live sensor readings from MQTT. No React build pipeline on the device.

const app = LightDraw.createApp('#dashboard', {
  width: 1024,
  height: 600,
  renderer: 'canvas'
});

app.loadJSON({
  type: 'group',
  children: [
    { type: 'thermometer', props: { value: 72, x: 24, y: 24, label: 'Line 3 Temp' } },
    { type: 'gauge', props: { value: 68, size: 120, x: 200, y: 24, label: 'Humidity %' } },
    {
      type: 'lineChart',
      props: {
        data: [18, 22, 31, 28, 35, 42, 38],
        width: 500,
        height: 180,
        x: 24,
        y: 180,
        title: 'Throughput (units/hr)'
      }
    },
    {
      type: 'statusBar',
      props: {
        segments: ['● Connected', 'MQTT', '1.2k msg/s'],
        x: 24,
        y: 400
      }
    }
  ]
});

Output:

What operators see: Gauges and charts update in real time. Status bar shows broker health. Entire UI fits in ~101 KB gzip (full bundle via CDN).

Use Case 2: Automotive Digital Cockpit

Scenario: An instrument cluster in an infotainment WebView, updating at 30–60 FPS from CAN bus or a driving simulator.

const app = LightDraw.createApp('#cluster', {
  width: 800,
  height: 480,
  renderer: 'canvas'
});

app.loadJSON({
  type: 'instrumentCluster',
  props: {
    theme: 'classic',
    width: 800,
    height: 480,
    speed: 0,
    rpm: 800,
    fuel: 100
  }
});

const cluster = app.stage.children[0];

function onDriveTick(canData) {
  LightDraw.applyDriveState(cluster, {
    speed: canData.speed,
    rpm: canData.rpm,
    fuel: canData.fuelPercent
  });
  app.requestRender();
}

Output:

What the driver sees: Speedometer at 95, tach at 3200 RPM, fuel at 68%. Smooth updates because render stays sub-millisecond for typical cluster node counts.

Use Case 3: AI-Generated Admin Panel

Scenario: Your internal copilot receives "Build a server health dashboard with CPU chart and acknowledge button." It outputs JSON, not React.

const app = LightDraw.createApp('#app', {
  width: 960,
  height: 540,
  renderer: 'html'
});

const scene = await agentResponse.json();

if (LightDraw.validateSceneJSON(scene).valid) {
  app.loadJSON(scene);
  app.setUiTheme({ preset: 'slate', mode: 'dark' });
}

Example LLM output (scene JSON):

{
  "type": "group",
  "children": [
    { "type": "card", "props": { "title": "Server health", "x": 16, "y": 16, "width": 420, "height": 200 } },
    { "type": "lineChart", "props": { "data": [22,35,28,48,41,55], "x": 32, "y": 56, "width": 380, "height": 140 } },
    { "type": "button", "props": { "label": "Acknowledge", "variant": "primary", "x": 480, "y": 200 } }
  ]
}

Output:

What the user sees: A card titled "Server health", CPU line chart trending upward, and a primary "Acknowledge" button — rendered in seconds, no codegen pipeline.

Use Case 4: Network / Architecture Diagram

Scenario: An SRE pastes an LLM-generated topology into an incident board during an outage.

app.loadJSON({
  type: 'networkTopology',
  props: {
    data: {
      nodes: [
        { id: 'gw', label: 'Gateway', type: 'router', x: 400, y: 40 },
        { id: 'api', label: 'API', type: 'server', x: 200, y: 160 },
        { id: 'db', label: 'Database', type: 'server', x: 400, y: 160 },
        { id: 'cache', label: 'Redis', type: 'server', x: 600, y: 160 }
      ],
      edges: [
        { from: 'gw', to: 'api' },
        { from: 'gw', to: 'db' },
        { from: 'api', to: 'cache' }
      ]
    }
  }
});

Output:

What you see: Router at top, three servers below, connectors auto-routed between nodes — not hand-drawn SVG paths.

Use Case 5: Embedded Control Panel (CDN, Zero Build)

Scenario: A Raspberry Pi kiosk controls industrial pumps. Firmware team delivers one HTML file. No npm on the device.

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lightdraw@1/dist/lightdraw.min.css">
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/lightdraw@1/dist/lightdraw.min.js"></script>
<script>
  const app = LightDraw.createApp('#app', { width: 480, height: 320, renderer: 'html' });
  app.loadJSON({
    type: 'group',
    children: [
      { type: 'toggle', props: { label: 'Pump A', value: true, x: 20, y: 20 } },
      { type: 'slider', props: { value: 60, width: 200, x: 20, y: 70, label: 'Flow rate %' } },
      { type: 'button', props: { label: 'Emergency stop', variant: 'danger', x: 20, y: 130 } },
      { type: 'statusBar', props: { segments: ['PLC Online', 'Pump A: RUN'], x: 20, y: 200 } }
    ]
  });
</script>

Output:

What the operator sees: Toggle for Pump A (on), slider at 60%, red emergency stop button, status bar showing PLC state.

Console output on interaction:

Control changed: toggle true
Control changed: slider 73
Control changed: button (click event)

How LightDraw Compares

LightDrawReact + Chart.jsD3.jsGoJS / commercial
Runtime deps0React + chart libD3License + lib
Full HMI in one package❌ assemble yourself❌ data-viz focusPartial
JSON → live UI❌ usually codegenSome import/export
Canvas 60 FPS sceneVia chart canvasManualVaries
ES5 / old WebView✅ legacy build❌ needs buildVaries
AI agent friendly✅ schema docs❌ outputs JSX
LicenseMITMITISCOften paid

LightDraw is not a React replacement. It's a graphics engine you embed inside any page or framework.

Try It Yourself

git clone https://github.com/rakeshrajena/lightDraw.git
cd lightDraw
npm install
npm run build
npm run dev:website   # → http://localhost:5173

Wrapping Up

If your project touches embedded web, real-time dashboards, automotive HMIs, or AI-generated UIs, the usual "assemble five libraries" approach costs you bundle size, validation complexity, and WebView compatibility headaches.

LightDraw gives you one scene graph, three renderers, JSON-first loading with validation, and domain modules that cover the widgets you'd otherwise glue together yourself. Start with a CDN script tag and loadJSON — you can have a working dashboard on screen before your npm install finishes elsewhere.

MIT licensed. Built for embedded web, dashboards, and AI-built UIs.