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

@drawmotive/textgraph

v0.3.1

Published

Render TextGraph flowcharts and directed graphs as PNG images in Node.js, browsers, React, and Web Workers.

Readme

TextGraph

Turn text into diagrams in your application.

Render flowcharts and directed graphs as PNGs or SVGs in Node.js, browsers, React, and Web Workers. TextGraph handles automatic layout and provides source validation and rendering diagnostics. The renderer runs where your code runs; no hosted rendering API or API key is required.

Documentation · Runnable examples · API reference

A few lines. A diagram.

(horizontal)

checkout(primary): Checkout {
  pay -> payment
  payment ->(dashed warning) pay : No, retry
}

fulfillment(success): Fulfillment {
  ship -> delivered
  email
}

payment -> ship : Yes
payment -> email : Yes

pay: Pay for order
payment(diamond fill primary): Paid?
ship: Ship order
email: Email receipt
delivered(ellipse fill success): Delivered

Online order: checkout and fulfillment, with a payment decision, a dashed retry loop, and parallel shipping and email receipt branches.

Open the full diagram · Copy the source · Try this diagram

For Chinese, Japanese, and color emoji, see the packaged font examples.

Keep source in version control and render again when relationships change. TextGraph uses a small, structured language; it does not interpret unrestricted prose.

Connections inside a group introduce that group's local nodes; no separate member list is needed. Group bodies also allow bare members, nested groups and comments. Connections can style their endpoints inline, such as browse(ellipse) -> checkout. Keep standalone node labels or styles at the root, in any order. At the root, a short name such as payment finds the node when that name is unique in the diagram.

shopping(info): Shopping {
  browse -> checkout
}
backend: Backend {
  payment -> saved
}

checkout -> payment
checkout: Place an order
payment(diamond): Payment accepted?

Here payment and backend.payment both refer to the backend node. Root connections and decorations keep its containment, even when they appear before the groups. An ungrouped node needs no separate declaration: a root arrow or decoration can introduce it.

The same name in two groups creates two nodes. Inside each group, short names refer to its local nodes. At the root, use a group prefix only when needed to distinguish matches:

Review { submit -> done }
Delivery { pack -> done }

Review.done -> pack
submit: Place an order
Review.done: Approved
Delivery.done: Delivered

done at the root is ambiguous and reports the matching qualified names. Group endpoints prefer a local member or group, then a unique declared group elsewhere. Ambiguous group names need a prefix. Nested names can use a unique suffix: with Outer { Backend { payment } }, payment, Backend.payment and Outer.Backend.payment all work when they identify a single object. A qualified connection endpoint may refer to another group's existing node without moving it. Unknown qualified names report an error.

Complete repeated-name example

Choose your workflow

| What you want to do | Use | Working example | | --- | --- | --- | | Generate diagrams for documentation, reports, or build jobs | Node.js: write PNG bytes or SVG text to a file | Node sample | | Embed live diagrams in dashboards or internal tools | React component and shared provider | React + Vite sample | | Add editable source and previews to a web app | Browser SDK | Plain JavaScript sample | | Keep the UI responsive while rendering larger diagrams | SDK in a module Web Worker | Worker sample | | Check syntax and references before rendering | The SDK's validate() method | Validation example |

For existing documentation, use the Markdown/VitePress plugin or VS Code Markdown extension.

Install

npm install @drawmotive/[email protected]

The current stable release is 0.3.0, available through latest. The alpha channel includes previews. New releases use canonical numeric versions; every numeric version is stable and publishes to the latest channel. Historical suffixed versions remain available. See release policy.

Supports Node.js 22 or a modern browser with WebAssembly and Web Crypto. Browser applications need HTTPS or localhost. React support is an optional entry in this package, compatible with React 18.2+ and 19.

Supported environments

| Layer | Supported environment | Verification boundary | | --- | --- | --- | | Node runtime and package tools | Node.js 22; npm 10 | Vite samples require Node 22.12+ on the 22 line | | Desktop build and Node rendering | Linux, Windows, macOS | CI targets all three systems with Node 22 | | Browser, React and module Worker rendering | Current Chromium, Firefox and WebKit engines | Playwright tests the SDK and samples on Linux; WebKit is not a Safari device certification | | React entry | React 18.2+ in the 18 line, or React 19 | React is an optional peer dependency |

The standalone audit on 2026-10-01 ran Linux x64 with Node 22.23.2 and npm 10.9.8. The support and CI targets above do not claim that Windows, macOS or every browser was executed in that audit. Browser hosts must provide WebAssembly, JavaScript modules, Web Crypto and a secure origin.

Render a PNG in Node.js

Save as render.mjs, then run node render.mjs:

import { writeFile } from "node:fs/promises";
import { initializeTextGraph } from "@drawmotive/textgraph/node";

const textgraph = await initializeTextGraph();
try {
  const result = await textgraph.renderPng("browser -> api -> database");
  if (result.success) {
    await writeFile("diagram.png", result.png);
    console.log("Saved diagram.png");
  } else {
    console.error(result.diagnostics);
    process.exitCode = 1;
  }
} finally {
  await textgraph.dispose();
}

Node reads the included runtime from the installed package. No browser, .NET installation, or asset-copy step is needed. Reuse an initialized instance for multiple diagrams, then dispose it when the job is finished.

Complete file-to-PNG sample →

For vector output, use the same initialized instance:

const vector = await textgraph.renderSvg("browser -> api -> database", { padding: 10 });
if (vector.success) {
  await writeFile("diagram.svg", vector.svg, "utf8");
}

SVG returns logical displayWidth and displayHeight. It accepts padding, language, and signal; raster settings such as scale apply only to PNG. React components continue to use PNG; browser and Worker SDK instances also expose renderSvg().

Add a diagram to React

For browser, React, and Worker applications, copy the runtime assets before starting development or building:

npx textgraph-copy-assets public/textgraph/wasm

Then render a component:

import { TextGraph, TextGraphProvider } from "@drawmotive/textgraph/react";
import type { TextGraphInitializeOptions } from "@drawmotive/textgraph";

const options: TextGraphInitializeOptions = {
  resolveAsset: (asset) => new URL(`/textgraph/${asset.path}`, location.origin),
};

export function Diagram({ source }: { source: string }) {
  return (
    <TextGraphProvider options={options}>
      <TextGraph source={source} alt="Service dependencies" />
    </TextGraphProvider>
  );
}

Changing source updates the image. For several diagrams, put one provider around their common parent. Loading states and rendering diagnostics are built in. The component renders on the main thread; use the Worker sample for heavier interactive workloads.

React + Vite sample → · React guide →

Render in a browser

After copying assets as shown above, use this in a bundled browser application:

import { initializeTextGraph } from "@drawmotive/textgraph/browser";

const textgraph = await initializeTextGraph({
  resolveAsset: (asset) => new URL(`/textgraph/${asset.path}`, location.origin),
});
try {
  const result = await textgraph.renderPng("browser -> api -> database", {
    encoding: "base64",
    scale: 2,
  });
  if (result.success) {
    const image = document.createElement("img");
    image.src = `data:image/png;base64,${result.png}`;
    image.alt = "Browser connects to API, which connects to database";
    image.width = result.displayWidth ?? result.width / 2;
    image.height = result.displayHeight ?? result.height / 2;
    image.style.maxWidth = "100%";
    image.style.height = "auto";
    document.body.append(image);
  } else {
    console.error(result.diagnostics);
  }
} finally {
  await textgraph.dispose();
}

For repeated edits, keep the runtime alive and dispose it when the editor closes. An async call still computes on its current thread; the Worker sample moves rendering off the UI thread.

Browser example → · Worker example →

Deploy the browser runtime

  • Add the asset-copy command to your application's predev and prebuild scripts.
  • Deploy the complete copied directory: WASM, JavaScript, fonts, themes, and licenses. Re-copy after SDK updates; keep SDK and runtime versions matched.
  • The resolver above assumes hosting at /. For a subdirectory, use your deployed base path; the Vite samples demonstrate import.meta.env.BASE_URL.

Asset hosting and CSP →

Validation and output options

On an initialized instance:

const validation = await textgraph.validate("browser -> api -> database");
console.log(validation.valid, validation.diagnostics);

const image = await textgraph.renderPng("browser -> api -> database", {
  scale: 2,
  padding: 24,
  maxWidth: 1200,
});

Validation checks parsing and semantic references; rendering additionally checks layout and output. Diagram failures return diagnostics. Operational failures reject with DrawMotiveError.

PNG output defaults to bytes, scale 1, padding 10, and a white background. Use higher scale for more pixels and returned display dimensions for web sizing. TypeScript declarations are included for every public entry point.

Full API and options →

Run the examples locally

Samples are complete applications in the public repository and pin the public @drawmotive/[email protected] package. To try the React sample from a fresh checkout:

git clone https://github.com/drawmotive/textgraph.git
cd textgraph
cd samples/react-vite
npm ci
npm run dev

Vite samples require Node.js 22.12+. Replace react-vite with browser or worker for those samples. The Node sample uses npm start instead. The shared sample guide also describes explicit development tarball testing. Samples are not included in the npm package.

Sample setup and deployment →

Current scope

  • Available: flowcharts and directed graphs, automatic layout, PNG and SVG rendering, and source validation.
  • Not available yet: mind maps, sequence diagrams, and slides.
  • Fonts: Noto Sans and Fuzzy Bubbles are included. Custom font descriptors and the optional published @drawmotive/[email protected] package are supported. See font configuration.

Project links

Language guide · Changelog · Report an issue · MIT license

For public checkout commands and pull requests, see Contributing. Redistribution notices are indexed in NOTICE. For vulnerability reports, see Security reporting.

Try it in a browser

Open the runnable HTML/JavaScript example to edit source, see its PNG and copy the integration code without installing anything. For visual editing, see the DrawMotive editor.