{"id":14678874,"url":"https://github.com/vizdom-dev/vizdom","last_synced_at":"2025-09-09T04:31:29.581Z","repository":{"id":246880234,"uuid":"823419403","full_name":"vizdom-dev/vizdom","owner":"vizdom-dev","description":"A diagrams-as-code library for TypeScript with zero dependencies","archived":false,"fork":false,"pushed_at":"2025-02-16T08:47:29.000Z","size":158,"stargazers_count":175,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-08T23:55:22.655Z","etag":null,"topics":["dag","dagre","diagramming","diagrams-as-code","graphs","graphviz","svg"],"latest_commit_sha":null,"homepage":"https://vizdom.dev","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vizdom-dev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-03T02:19:50.000Z","updated_at":"2025-08-05T13:39:25.000Z","dependencies_parsed_at":"2025-01-29T21:19:20.249Z","dependency_job_id":"2b3df072-2fb9-41cb-962b-a8fc1d508aad","html_url":"https://github.com/vizdom-dev/vizdom","commit_stats":null,"previous_names":["vizdom-dev/vizdom-ts"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vizdom-dev/vizdom","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vizdom-dev%2Fvizdom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vizdom-dev%2Fvizdom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vizdom-dev%2Fvizdom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vizdom-dev%2Fvizdom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vizdom-dev","download_url":"https://codeload.github.com/vizdom-dev/vizdom/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vizdom-dev%2Fvizdom/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274243987,"owners_count":25248156,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-09T02:00:10.223Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dag","dagre","diagramming","diagrams-as-code","graphs","graphviz","svg"],"created_at":"2024-09-12T10:01:37.511Z","updated_at":"2025-09-09T04:31:29.563Z","avatar_url":"https://github.com/vizdom-dev.png","language":null,"funding_links":[],"categories":["Others"],"sub_categories":[],"readme":"# Vizdom\n\nVizdom is a declarative graph layout and rendering engine compiled from Rust to\nWebAssembly using `wasm-pack`. It provides an API for creating and rendering\ndirected graphs and producing SVGs.\n\n## Goals\n\n- 💾 **Low memory footprint**\n- 🎉 **No system dependencies**\n- 🚀 **Fastest layout and rendering engine powered by WebAssembly**\n- 🔥 **Works in any client / server configuration**\n\n## Features\n\n- 🛠️ Create and manipulate **directed** graphs.\n- 🔀 Handles multiple edges with the same `source` and `target` nodes.\n- 🔄 Render **cyclical** directed graphs.\n- 🎨 Support various custom rendering attributes for enhanced visualization.\n\n## Installation\n\nVizdom comes in several distributions:\n\n- `esm` (Modules)\n- `node` (CJS)\n- `web` (Browser)\n\nSimply select a distribution and install using your favorite package manager\nfollowing the naming convention `@vizdom/vizdom-ts-\u003cdist\u003e`.\n\n```bash\n# If using Node or Bun\nnpm install @vizdom/vizdom-ts-node\n\n# If using a bundler such as Vite\nnpm install @vizdom/vizdom-ts-esm\n\n# If using Angular (without SSR)\nnpm install @vizdom/vizdom-ts-web\n```\n\n## Vite\n\nVizdom supprots Vite using the `esm` distribution. You can use either CSR or\nSSR. Vitest + Asto will need a bit of a hack to get the testing suite to use the\n`node` bundle. See [this issue](https://github.com/vizdom-dev/vizdom/issues/9)\nfor a minimal configuration.\n\n## Angular\n\nVizdom supports Angular, but unfortunatly you cannot customize the Vite\nconfiguration. As a result, the only way I know how to get it running is to use\nthe `web` distribution which doesn't support SSR. See [this\nissue](https://github.com/vizdom-dev/vizdom/issues/9) for a minimal\nconfiguration.\n\n## 🚴 Usage\n\nIn the most basic configuration, all you need is to provide labels for nodes and\nedges.\n\nWrite this into a `index.ts` file:\n\n```typescript\nimport { DirectedGraph } from \"@vizdom/vizdom-ts-node\";\n// ... or CJS\n// const { DirectedGraph } = require(\"@vizdom/vizdom-ts-node\");\n\n// Create a new graph\nconst graph = new DirectedGraph();\n\n// Add vertices\nconst v0 = graph.new_vertex({\n  render: {\n    label: \"Hello\",\n  },\n});\nconst v1 = graph.new_vertex({\n  render: {\n    label: \"World!\",\n  },\n});\n\n// Add an edge between the vertices\ngraph.new_edge(v0, v1, {\n  render: {\n    label: \"Foo Bar\",\n  },\n});\n\n// Position the graph\nconst positioned = graph.layout();\n\n// Finally, obtain to an SVG\nawait fs.writeFile(\"./graph.svg\", positioned.to_svg().to_string());\n```\n\nThen, run the file:\n\n```sh\nnpx tsx index.ts\n# Or with Bun\nbun run index.ts\n```\n\nWhich will generate a graph that looks like:\n\n![this](examples/basic/graph.svg)\n\n### ☁️ Online Mode\n\nVizdom offers an online mode that effortlessly syncs your graph with your Vizdom\naccount, eliminating the need for manual positioning and rendering. This ensures\nyour graph is always up-to-date with your latest code changes.\n\nTo get started with syncing, [sign up for an\naccount](https://vizdom.dev/auth/signup).\n\nOnce you have an account, syncing your graph is straightforward. Simply add a\nfew additional parameters when constructing your graph:\n\n```typescript\nconst graph = new DirectedGraph(\n  {}, // \u003c-- Optional layout and render attributes.\n  // Must be specified as the second argument.\n  {\n    client_id: process.env.VIZDOM_CLIENT_ID || \"\",\n    client_secret: process.env.VIZDOM_CLIENT_SECRET || \"\",\n    graph_id: process.env.VIZDOM_GRAPH_ID || \"\",\n  }\n);\n```\n\nBy specifying these parameters when creating your graph, you can easily manage\nmultiple graphs within the same project, each syncing independently.\n\n## Layout Engine\n\nVizdom can be used as a pure layout engine to obtain positioning information,\nwhich is especially useful if you already have a method for rendering your\ngraph.\n\n### Specifying Layout Parameters\n\nTo use Vizdom for layout purposes, you need to provide the bounding box\ndimensions. If you are using the library in a browser context, you can retrieve\nthese dimensions by using methods like\n[getBoundingClientRect()](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect)\non the HTML element. Compute the `shape_w` (width) and `shape_h` (height) and\npass them as `layout` parameters.\n\nAdditionally, there's an optional argument, `compute_bounding_box`, which can be\nset to `false`. This tells the library to use the provided layout values for the\nbounding box instead of computing it from the `label` attribute. By default, the\nshape is considered to be a `Shape.Rectangle` for nodes and `Shape.Plaintext`\nfor edges (which is also a rectangle) and should remain unchanged in this\ncontext.\n\n### Providing IDs\n\nEach vertex and edge requires an `id` to map the JSON result correctly. The\nresulting JSON string will include these IDs, enabling accurate mapping of the\nnodes and edges.\n\n```typescript\n// ...\nconst v0 = graph.new_vertex(\n  {\n    layout: {\n      shape_w: 10,\n      shape_h: 10,\n    },\n    render: {\n      id: \"v0\",\n    },\n  },\n  {\n    compute_bounding_box: false,\n  }\n);\n\n// ...\n\n// Similarly, for an edge you have the same API.\nconst e0 = graph.new_edge(\n  v0,\n  v1,\n  {\n    layout: {\n      shape_w: 10,\n      shape_h: 10,\n    },\n    render: {\n      id: \"e1\",\n    },\n  },\n  {\n    compute_bounding_box: false,\n  }\n);\n\n// Position the graph\nconst positioned = graph.layout();\n\n// Obtain the json instance\nconst json = positioned.to_json();\n\n// Get a JS/TS Object adhereing to the `IJsonPosition` interface.\nconst jsonObj = json.to_obj();\n\n// Or get the JSON string directly\nconst jsonString: string = json.to_string();\n// const jsonStringPretty: string = json.to_string_pretty();\n```\n\nFor a practical example, check out the [json example](examples/json/index.ts),\nwhich generates a positional JSON string similar to\n[this](examples/json/graph.json).\n\n## Styling Attributes\n\nVizdom supports several layout and rendering options for those who want more\ncontrol over the appearance of their graphs.\n\n```typescript\nconst v0 = graph.new_vertex({\n  render: {\n    label: \"Foo\",\n    color: \"#ff2f8e\",\n    fill_color: \"#ff2f8eaa\",\n    shape: Shape.Triangle,\n    style: VertexStyle.Dashed,\n  },\n});\n```\n\nCheck out the [style example](examples/styles/index.ts), which produces a graph\nthat looks like:\n\n![this](examples/styles/graph.svg)\n\n## DOT Language Support\n\nVizdom offers partial support for the [DOT\nlanguage](https://graphviz.org/doc/info/lang.html), commonly used for defining\ngraphs. Most styling attributes are supported; however, please note that\nundirected diagrams are currently not parsed. Additionally, while DOT files may\nspecify layout engines, Vizdom will always use its own layout engine for\npositioning.\n\nThe parser fully supports [cluster\ngraphs](https://graphviz.org/docs/attrs/cluster/), allowing for `subgraph` IDs\nwith the `cluster_` prefix or `subgraph` **statements** containing a\n`cluster=true` attribute.\n\nUnsupported styles are gracefully ignored, defaulting to safe visual options to\nensure smooth rendering.\n\n```typescript\nimport { DotParser } from \"@vizdom/vizdom-ts-node\";\n// ... or CJS\n// const { DotParser } = require(\"@vizdom/vizdom-ts-node\");\n\n// Create a new Dot Parser\nconst parser = new DotParser();\nconst dotGraph = parser.parse(\"digraph { a -\u003e b }\");\nconst directedGraph = dotGraph.to_directed();\nconst positioned = directedGraph.layout();\n\n// Once positioned, the graph can be exported as SVG or JSON.\nawait fs.writeFile(\"./graph.svg\", positioned.to_svg().to_string());\nconst jsonObj = positioned.to_json().to_obj();\nconsole.log(\n  util.inspect(jsonObj, { showHidden: false, depth: null, colors: true })\n);\n```\n\nCheck out the [dot example](examples/dot/index.ts), which produces a graph that\nlooks like:\n\n![this](examples/dot/graph.svg)\n\nYou may also sync a parsed DOT to your Vizdom account by specifying the options\nlike the following:\n\n```typescript\n// ...\nconst parser = new DotParser({\n  client_id: process.env.VIZDOM_CLIENT_ID || \"\",\n  client_secret: process.env.VIZDOM_CLIENT_SECRET || \"\",\n  graph_id: process.env.VIZDOM_GRAPH_ID || \"\",\n});\nconst dotGraph = parser.parse(\"digraph { a -\u003e b }\");\n// Sync complete!\n```\n\nOnce synced to Vizdom, there's no need to manually convert the parsed AST to a\ndirected graph (`to_directed()`), apply layout (`layout()`) nor rendering\n(`to_svg()`, `to_json()`) methods. These processes are automatically handled in\nthe browser when viewing your graph.\n\n## 📈 Diff Viewer 📉\n\nYou can visually compare two graphs with Vizdom. Ensure that the `id` attributes\nare set and unique to track changes effectively. The resulting graphs will be\nannotated with a 'glow' effect to highlight differences:\n\n- ❌ Removed elements (`id` no longer exists) are highlighted in **red**.\n- ✅ Added elements (`id` is new) are highlighted in **green**.\n- 🟧 Modified elements (`id` is the same, but other attributes have changed) are\n  highlighted in **orange**.\n\nCheck out the [diff example](examples/diff/index.ts), which produces two graphs\nthat look like:\n\n![graph 0](examples/diff/graph0.svg)\n\nand\n\n![graph 1](examples/diff/graph1.svg)\n\n## License\n\nLicensed under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file\nor visit\n[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)\n\n## Third Party Licenses\n\nThis project makes use of third-party components, each with its own licensing\nterms:\n\n- **Dagre.js**: Some of the layout algorithms in this project are inspired by\n  [Dagre.js](https://github.com/dagrejs/dagre), which is licensed under the MIT\n  License. The full license text can be found in the\n  [`third_party/dagre/LICENSE`](third_party/dagre/LICENSE) file.\n\n- **NotoSans Font**: The NotoSans font used in this project is licensed under\n  the SIL Open Font License. The full license text can be found in the\n  [`third_party/noto_sans/LICENSE`](third_party/noto_sans/LICENSE) file.\n\n- **Others**: Can be found in the\n  [`third_party/licenses.html`](third_party/licenses.html) file.\n\n## Closed-Source Notice\n\nPlease note that while Vizdom is freely available for use under the Apache\nLicense 2.0, the Rust WebAssembly binary included in this library is\nclosed-source. You are free to use the library, but the source code for the Rust\nWebAssembly binary is not publicly available.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvizdom-dev%2Fvizdom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvizdom-dev%2Fvizdom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvizdom-dev%2Fvizdom/lists"}