npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

lightdraw

v1.2.1

Published

Zero-dependency 2D graphics engine for dashboards (multi-series charts, dataTable), automotive HMIs & telltales, interactive diagrams (wire flow, status tint, CAN bus hops, built-in play/pause/zoom toolbar, rotate, smart routing), UI components, and AI-fr

Readme


See it in action


The problem LightDraw solves

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

| Typical stack | Pain | |---------------|------| | React + Chart.js + D3 + diagram lib | Large bundle, framework lock-in, many APIs to learn | | Raw Canvas API | No scene graph, manual hit-testing, no animation timeline | | Low-code / AI UI generators | Output is React/HTML code — hard to embed in WebView or validate | | Automotive HMI tools | Expensive, closed, or not web-native |

LightDraw replaces that stack with one zero-dependency engine:

  • Retained-mode scene graph — add/move/animate nodes; renderer draws efficiently
  • Three renderers — pick Canvas (performance), SVG (vectors), or HTML (accessibility + legacy WebView)
  • JSON scenes — validate, load, 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 transpiler at runtime

What you get (benefits)

| Benefit | What it means for you | |---------|------------------------| | Zero runtime deps | No npm install react chart.js d3. Smaller attack surface, simpler audits. | | Pay for what you load | lightdraw/core ~43 KB gzip; add dashboard, automotive, or diagram plugins only if needed. | | Ship faster | loadJSON(scene) for whole dashboards; app.setUiTheme({ preset: 'dark' }) — no custom CSS required. | | AI-ready | Schema docs + validateSceneJSON / parseAndValidateSceneJSON with path + expected-value hints — LLM output becomes a live UI in one call. | | Embed anywhere | CDN script tag, npm ESM, or ES5 UMD in Android WebView / Qt WebEngine. | | Export & audit | PNG, SVG, PDF, JSON, offline HTML from the same scene. | | Production tested | 1 600+ tests, size gates, benchmark regression, visual smoke on demos. |


When to use LightDraw (and when not to)

| ✅ Use LightDraw when… | ❌ Consider something else when… | |------------------------|----------------------------------| | Embedded dashboard or HMI in WebView | You need a full SPA framework (routing, SSR) — use React/Vue with LightDraw in a panel, or alone | | AI/low-code generates JSON UIs | You only need static marketing pages | | Automotive cluster, gauges, CAN-style visuals | 3D / WebGL games (use Three.js / Babylon) | | Flowcharts, network topology, org charts | Heavy document editing (Google Docs–class) | | Canvas performance + interaction (drag, zoom) | You already have D3-only data-viz and don't need widgets/HMI | | Legacy ES5 targets without bundlers | You need native mobile UI (use Swift/Kotlin) |


Quick start

npm install lightdraw
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lightdraw@1/dist/lightdraw.min.css">
<div id="app" style="position:relative;width:100%;height:480px"></div>
<script src="https://cdn.jsdelivr.net/npm/lightdraw@1/dist/lightdraw.min.js"></script>
<script>
  const app = LightDraw.createApp('#app', {
    width: 800,
    height: 480,
    background: '#0f172a',
    renderer: 'canvas',
  });
</script>
import LightDraw from 'lightdraw';
const app = LightDraw.createApp('#app', { renderer: 'canvas' });

| Import path | Use case | |-------------|----------| | lightdraw | Everything in one bundle (~169 KB gzip) | | lightdraw/core | Shapes + canvas only (~43 KB gzip) | | lightdraw/dashboard | Charts, gauges, multi-series, dataTable | | lightdraw/automotive | Cluster, telltales, Individual dash | | lightdraw/diagram | Flowchart, network, CAN, editor, wire flow + toolbar | | lightdraw/legacy | ES5 UMD for WebView |


Diagram examples (JSON → LightDraw)

Define a scene object, then load it. Same pattern for every diagram type.

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

function mountDiagram(scene) {
  app.clear();
  const chart = LightDraw.Diagram.fromJSON(scene.type, scene.props, app);
  app.add(chart);
  LightDraw.Diagram.fitToBounds(chart, 800, 480, 24);
  LightDraw.Diagram.installEditor(app, chart, {
    mode: 'arrange',
    allowResize: true,
    allowRotate: true,
  });
  return chart;
}

// Or: app.loadJSON(scene) when the root type is a registered diagram / group

| type | Notes | |--------|--------| | flowchart | Decisions, process, terminals + wire flow | | stateMachine | States + transitions | | processPipeline | Stages with status badges | | networkTopology | Visio/Cisco-style icons | | canNetwork | ECU bus + optional frame paths | | electricalSchematic | IEC symbols + wires | | classDiagram | UML classes + relations | | mindMap | Center + branches | | orgChart | Hierarchy cards (collapse in editor) |

Flowchart + wire flow

const flowchartScene = {
  type: 'flowchart',
  props: {
    width: 800,
    height: 480,
    data: {
      nodes: [
        { id: 'start', label: 'Start', type: 'start', x: 360, y: 24 },
        { id: 'check', label: 'Valid input?', type: 'decision', x: 360, y: 110 },
        { id: 'process', label: 'Process data', type: 'process', x: 360, y: 210 },
        { id: 'end', label: 'Complete', type: 'end', x: 360, y: 300 },
      ],
      edges: [
        { from: 'start', to: 'check' },
        { from: 'check', to: 'process', label: 'Yes' },
        { from: 'check', to: 'end', label: 'No' },
        { from: 'process', to: 'end' },
      ],
    },
    flow: {
      enabled: true,
      mode: 'both',
      playback: 'loop',
      statusHighlight: true,
      paths: [
        ['start', 'check', 'process', 'end'],
        ['start', 'check', 'end'],
      ],
      // chrome: true by default → ▶⏸↻ + zoom
    },
  },
};
mountDiagram(flowchartScene);

State machine

const stateMachineScene = {
  type: 'stateMachine',
  props: {
    width: 800,
    height: 400,
    data: {
      states: [
        { id: 'idle', label: 'Idle', x: 80, y: 120 },
        { id: 'run', label: 'Running', x: 320, y: 120 },
        { id: 'done', label: 'Done', x: 560, y: 120, kind: 'final' },
      ],
      transitions: [
        { from: 'idle', to: 'run', label: 'start' },
        { from: 'run', to: 'done', label: 'finish' },
      ],
    },
    flow: {
      enabled: true,
      mode: 'both',
      paths: [['idle', 'run', 'done']],
    },
  },
};
mountDiagram(stateMachineScene);

Pipeline

const pipelineScene = {
  type: 'processPipeline',
  props: {
    width: 800,
    height: 280,
    stages: [
      { id: 'ingest', label: 'Ingest', status: 'done', type: 'input' },
      { id: 'build', label: 'Build', status: 'active', type: 'build' },
      { id: 'deploy', label: 'Deploy', status: 'pending', type: 'deploy' },
    ],
    flow: {
      enabled: true,
      mode: 'both',
      path: ['ingest', 'build', 'deploy'],
    },
  },
};
mountDiagram(pipelineScene);

Network topology

const networkScene = {
  type: 'networkTopology',
  props: {
    width: 800,
    height: 400,
    data: {
      nodes: [
        { id: 'fw', label: 'NGFW', type: 'ngfw', x: 360, y: 40 },
        { id: 'web', label: 'Web', type: 'server', x: 200, y: 180 },
        { id: 'db', label: 'SQL', type: 'sql_database', x: 520, y: 180 },
      ],
      edges: [
        { from: 'fw', to: 'web' },
        { from: 'fw', to: 'db' },
      ],
    },
    flow: {
      enabled: true,
      mode: 'both',
      paths: [['fw', 'web'], ['fw', 'db']],
    },
  },
};
mountDiagram(networkScene);

CAN bus

const canScene = {
  type: 'canNetwork',
  props: {
    width: 800,
    height: 360,
    x: 0,
    y: 40,
    data: {
      busLabel: 'CAN HS · 500 kbps',
      ecus: [
        { id: 'ecm', label: 'ECM', address: '0x7E0' },
        { id: 'tcu', label: 'TCU', address: '0x7E1' },
        { id: 'abs', label: 'ABS', address: '0x7E2' },
      ],
    },
    flow: {
      enabled: true,
      mode: 'both',
      paths: [['ecm', 'tcu', 'abs']],
    },
  },
};
mountDiagram(canScene);

Schematic

const schematicScene = {
  type: 'electricalSchematic',
  props: {
    width: 800,
    height: 360,
    components: [
      { id: 'bat', type: 'battery', x: 80, y: 120 },
      { id: 'sw', type: 'spst', x: 220, y: 120 },
      { id: 'led', type: 'led', x: 360, y: 120 },
      { id: 'gnd', type: 'ground', x: 360, y: 220 },
    ],
  },
};
mountDiagram(schematicScene);

UML class diagram

const umlScene = {
  type: 'classDiagram',
  props: {
    width: 800,
    height: 400,
    data: {
      classes: [
        { id: 'shape', name: 'Shape', x: 120, y: 60, methods: ['draw()'] },
        { id: 'rect', name: 'Rect', x: 400, y: 60, methods: ['draw()'] },
      ],
      relations: [{ from: 'rect', to: 'shape', type: 'inheritance' }],
    },
    flow: {
      enabled: true,
      mode: 'both',
      paths: [['rect', 'shape']],
    },
  },
};
mountDiagram(umlScene);

Mind map

const mindMapScene = {
  type: 'mindMap',
  props: {
    width: 800,
    height: 400,
    center: 'LightDraw',
    branches: [
      { label: 'Core', children: ['Shapes', 'Renderers'] },
      { label: 'Modules', children: ['Diagram', 'Dashboard'] },
    ],
  },
};
mountDiagram(mindMapScene);

Org chart

const orgScene = {
  type: 'orgChart',
  props: {
    width: 900,
    height: 480,
    root: {
      name: 'CEO',
      role: 'Chief Executive',
      children: [
        { name: 'CTO', role: 'Engineering', children: [{ name: 'Lead' }] },
        { name: 'CFO', role: 'Finance' },
      ],
    },
  },
};
mountDiagram(orgScene);

| Library API | What it does | |-------------|--------------| | Diagram.fromJSON / app.loadJSON | Build from scene object | | installEditor | Drag, 8-handle resize, rotate, wire bends | | applyFlow / pauseFlow / replayFlow | Wire animation + status tint | | Built-in toolbar | Auto when flow.enabled (opt out: chrome: false) |

Guides: diagram-flow.md · diagram-module-schema.md · Demo: demo-diagram.html


Animation (shapes + timelines)

Low-level motion on any node — easing, path follow, stagger:

const animationScene = {
  type: 'group',
  children: [
    {
      type: 'circle',
      props: { id: 'dot', x: 80, y: 120, radius: 14, fill: '#38bdf8' },
    },
  ],
};

app.loadJSON(animationScene);
const dot = app.stage.getChildById?.('dot') || app.stage.children[0]?.children?.[0];

dot.animate({
  to: { x: 520, y: 120, scaleX: 1.4, scaleY: 1.4 },
  duration: 900,
  easing: 'easeInOutCubic',
  yoyo: true,
  repeat: Infinity,
});

Wire-level storytelling uses diagram flow (above), not raw dashOffset.
Demo: demo-animation.html · Guide: animation-guide.md


More use cases

IoT / ops dashboard

const dashboardScene = {
  type: 'group',
  children: [
    { type: 'thermometer', props: { value: 72, x: 24, y: 24 } },
    {
      type: 'lineChart',
      props: {
        width: 400,
        height: 160,
        x: 24,
        y: 120,
        series: [
          { name: 'CPU', data: [18, 22, 31, 28, 35] },
          { name: 'Mem', data: [40, 42, 45, 44, 48] },
        ],
      },
    },
    { type: 'gauge', props: { value: 68, diameter: 110, x: 480, y: 40 } },
  ],
};
app.loadJSON(dashboardScene);

Automotive cluster + drive feed

const clusterScene = {
  type: 'instrumentCluster',
  props: { theme: 'classic', width: 800, height: 480, speed: 0, rpm: 800, fuel: 100 },
};
app.loadJSON(clusterScene);
const cluster = app.stage.children[0];
LightDraw.applyDriveState(cluster, { speed: 95, rpm: 3200, fuel: 68, checkEngine: true });
app.requestRender();

CDN control panel (no build)

<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' });
  const panelScene = {
    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 } },
      { type: 'button', props: { label: 'Emergency stop', variant: 'danger', x: 20, y: 130 } },
    ],
  };
  app.loadJSON(panelScene);
</script>

Three ways to build a UI

| Method | Best for | Example | |--------|----------|---------| | JavaScript API | Custom logic, animation, events | app.circle({...}).animate({...}) | | JSON loadJSON | AI, configs, CMS, reproducible scenes | { type: 'gauge', props: { value: 72 } } | | HTML host page | CDN / embedded — not custom tags | <div id="app"> + script above |

LightDraw does not use <lightdraw-button> web components. HTML is the shell; JS or JSON builds the scene.


Benchmarks & bundle size

npm run build && npm run benchmark && npm run benchmark:compare

| Nodes | Render (canvas) | Hit test | |------:|----------------:|---------:| | 1 000 | ~0.46 ms | ~0.01 ms | | 5 000 | ~1.16 ms | ~0.01 ms |

| Package | Size (gzip) | Typical use | |---------|------------:|-------------| | lightdraw/core | ~43 KB | Games, custom canvas | | lightdraw (full) | ~169 KB | CDN one-liner | | lightdraw/diagram | ~73 KB | Editor + flow + toolbar | | lightdraw/dashboard | ~43 KB | Charts + dataTable | | lightdraw/automotive | ~31 KB | Cluster + telltales | | lightdraw/ui | ~16 KB | Form controls |


What's new in v1.2.1

Full notes: v1.2.1-release-notes.md · CHANGELOG

  • Built-in diagram ▶/⏸/↻ + zoom toolbar when flow.enabled (flow.chrome: false to opt out)
  • Demo uses the library overlay (no duplicate HTML chrome)
  • README: JSON scene examples for all diagram types + wire-flow GIF

Earlier in v1.2.0: wire flow status tint, CAN bus hops, smart routing, multi-series / dataTable, telltales, compact JSON — v1.2 notes

npm install [email protected]

AI & LLM integration

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

| Schema | Link | |--------|------| | UI | ui-components-schema.md | | Dashboard | dashboard-widgets-schema.md | | Automotive | automotive-widgets-schema.md | | Diagram | diagram-module-schema.md · diagram-flow.md |

Guide: ai-integration-guide.md


Live demos & docs

| | | |--|--| | Playground | rakeshrajena.github.io/lightDraw | | Diagram | #diagram | | Help | help.html | | npm | npmjs.com/package/lightdraw | | Docs index | docs/README.md |

Local: npm run build && npm run prepare:website && npm run dev:website


Browser support

Chromium 49+, Chrome, Firefox, Edge, Safari, Android WebView, Qt WebEngine.
Legacy: legacy-browser-guide.md.


Development

git clone https://github.com/rakeshrajena/lightDraw.git
cd lightDraw && npm install && npm run build
npm test
npm run ci:local

See CONTRIBUTING.md.


License

MIT — LICENSE


Author

Rakesh Ranjan Jena · GitHub · Website

Made with ❤️ for embedded web, dashboards, and AI-built UIs.