Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@ts-graphviz/core

ts-graphviz2.8mMIT3.0.2TypeScript support: included

Graphviz Models for Object-Oriented Programming

graphviz, dot

readme

Main CodeQL License: MIT All Contributors

OpenSSF Best Practices OpenSSF Scorecard Tidelift

npm version node version deno version npm

@ts-graphviz/core

Models and functions provided to users for the ts-graphviz library.

🔗

GitHub npm Reference Ask DeepWiki

Sponsor OpenCollective

format: Biome test: Vitest build: Vite


It is part of the ts-graphviz library, which is split into modular packages to improve maintainability, flexibility, and ease of use.

Features

The package adheres to object-oriented programming principles, allowing for:

  • Creation and manipulation of graph elements
  • Composition of complex graph structures
  • Extension through inheritance and customization
  • Type-safe graph construction with TypeScript

Usage Patterns

@ts-graphviz/core supports several patterns for creating and manipulating graphs:

Basic Object Creation

The most straightforward approach is to instantiate the model classes directly:

// Create a directed graph
const graph = new Digraph();

// Create nodes with attributes
const node1 = new Node('node1', { color: 'red' });
const node2 = new Node('node2', { color: 'blue' });

// Create an edge between nodes with attributes
const edge = new Edge([node1, node2], { label: 'Edge Label' });

// Add elements to the graph
graph.addNode(node1);
graph.addNode(node2);
graph.addEdge(edge);

Factory Methods

Graph models provide factory methods to create and automatically add elements:

// Create a directed graph
const graph = new Digraph();

// Create and add nodes using factory methods
const node1 = graph.createNode('node1', { color: 'red' });
const node2 = graph.createNode('node2', { color: 'blue' });

// Create and add an edge using factory method
graph.createEdge([node1, node2], { label: 'Edge Label' });

Composition with Subgraphs

Graphs can be composed with subgraphs to create hierarchical structures:

// Create a directed graph
const graph = new Digraph();

// Create a subgraph
const subgraph = new Subgraph('cluster_0');

// Create nodes in the subgraph
const node1 = new Node('node1');
const node2 = new Node('node2');

// Add nodes to the subgraph
subgraph.addNode(node1);
subgraph.addNode(node2);

// Add the subgraph to the main graph
graph.addSubgraph(subgraph);

Customization and Extension

@ts-graphviz/core provides several mechanisms for customizing and extending its functionality:

Class Inheritance

You can create custom graph element classes by extending the base classes:

class MyCustomNode extends Node {
  constructor(id: string) {
    super(`node_${id}`, {
      label: `Custom Node ${id}`,
      shape: 'box'
    });
  }
}

class MyCustomEdge extends Edge {
  constructor(targets: EdgeTargetTuple) {
    super(targets, {
      color: 'blue',
      penwidth: '2.0'
    });
  }
}

// Use custom classes
const node1 = new MyCustomNode('A');
const node2 = new MyCustomNode('B');
const edge = new MyCustomEdge([node1, node2]);

Models Context API

The Models Context API allows you to specify which model classes should be used when creating graph element.

This is implemented through the with method on graph models:

// Create a directed graph
const graph = new Digraph();

// Set up the context with custom classes
graph.with({
  Node: MyCustomNode,
  Edge: MyCustomEdge
});

// Now factory methods will use the custom classes
const nodeA = graph.createNode('A'); // Creates a MyCustomNode
const nodeB = graph.createNode('B'); // Creates a MyCustomNode
const edge = graph.createEdge([nodeA, nodeB]); // Creates a MyCustomEdge

Integration with AST

@ts-graphviz/core integrates with @ts-graphviz/ast to convert between the object model and the DOT language.

This integration enables:

  • Converting graph models to DOT strings
  • Parsing DOT strings into graph models
  • Working with the abstract syntax tree directly

The main conversion functions that link @ts-graphviz/core with @ts-graphviz/ast are:

  • fromModel: Converts a graph model to an AST
  • toModel: Converts an AST to a graph model

These are then used by the main ts-graphviz package to implement the toDot and fromDot functions.

Contributors 👥

Thanks goes to these wonderful people (emoji key):

Yuki Yamazaki
Yuki Yamazaki

💻 ⚠️ 📖 🤔
LaySent
LaySent

🐛 ⚠️
elasticdotventures
elasticdotventures

📖
Christian Murphy
Christian Murphy

💻 🤔 📖
Artem
Artem

🐛
fredericohpandolfo
fredericohpandolfo

🐛
diegoquinteiro
diegoquinteiro

🐛
robross0606
robross0606

🤔
Blake Regalia
Blake Regalia

🐛
bigbug
bigbug

💬
mrwk
mrwk

💬
svdvonde
svdvonde

💬
Adam
Adam

💬
Trevor Scheer
Trevor Scheer

️️️️♿️
Prem Pillai
Prem Pillai

🐛
nagasawaryoya
nagasawaryoya

💻 ⚠️
YukiSasaki
YukiSasaki

💻 ⚠️
Madd0g
Madd0g

🐛
j4k0xb
j4k0xb

🐛
HKrogstie
HKrogstie

🐛
Nils K
Nils K

🐛
hao2013
hao2013

🚧 👀
Walter Rafelsberger
Walter Rafelsberger

💬
grsjst
grsjst

🐛
Steve
Steve

🐛

This project follows the all-contributors specification. Contributions of any kind welcome!

Changelog 📜

See CHANGELOG.md for more details.

License ⚖️

This software is released under the MIT License, see LICENSE.

changelog

@ts-graphviz/core

3.0.2

Patch Changes

3.0.1

Patch Changes

3.0.0

Major Changes

  • #1363 9328563 Thanks @kamiazya! - 🚨 Breaking Changes: Drop Node.js 18 support

    Minimum required version is now Node.js 20+

    ESM-Only Distribution

    • Remove CommonJS builds: All packages now distribute only ESM (ECMAScript Modules)
    • Package exports: Removed require fields from package.json exports
    • Module type: All packages are now "type": "module"

    🔄 Migration Guide

    {
      "type": "module"
    }
    // Import syntax remains unchanged
    import { Digraph, Node, Edge, toDot } from "ts-graphviz";
    import { toFile } from "ts-graphviz/adapter";
    import { parse } from "ts-graphviz/ast";

    For CommonJS Projects

    If you are using CommonJS (CJS) and need to migrate to ESM, you will need to update your project to support dynamic imports. This is necessary because the packages no longer provide CommonJS builds.

    Before (CJS)

    // JavaScript (CommonJS)
    function createGraph() {
      // Dynamic import is required because the packages no longer provide CommonJS builds.
      const { Digraph, Node, Edge, toDot } = require("ts-graphviz");
      const graph = new Digraph();
      return toDot(graph);
    }

    After (ESM)

    async function createGraph() {
      const { Digraph, Node, Edge, toDot } = await import("ts-graphviz");
    
      const graph = new Digraph();
      // Create your graph...
      return toDot(graph);
    }
    // TypeScript (CommonJS)
    // Update tsconfig.json
    {
      "compilerOptions": {
        "module": "Node16",
        "moduleResolution": "Node16"
      }
    }
    
    // Use dynamic imports
    async function createGraph() {
      const tsGraphviz = await import('ts-graphviz');
      const { Digraph, Node, Edge, toDot } = tsGraphviz;
    
      const graph = new Digraph();
      // Create your graph...
      return toDot(graph);
    }

    🎯 Benefits

    • Modern JavaScript: Leveraging native ES modules for better performance
    • Smaller bundle sizes: ESM enables better tree-shaking
    • Future-proof: Aligning with the JavaScript ecosystem direction
    • Better TypeScript support: Enhanced module resolution

Minor Changes

  • #1363 9328563 Thanks @kamiazya! - Define Supported environment and Support levels

    To provide clarity on the environments in which ts-graphviz operates, we have categorized support levels:

    Support Levels

    Tier 1: Full Support

    • Definition: Environments that are fully supported, with comprehensive automated testing and maintenance.
    • Environments:
      • Node.js LTS versions: All active Long-Term Support (LTS) versions.
        • If a Node.js LTS version is released, we will ensure compatibility with it.
        • If a Node.js LTS version is deprecated, we will drop support for it in the next major release.
    • Details:
      • We run automated tests on all LTS versions of Node.js.
      • Full compatibility and performance are ensured.
      • Critical issues are prioritized for fixes.

    Tier 2: Active Support

    • Definition: Environments that receive active support with limited automated testing.
    • Environments:
      • Deno Latest LTS version: The latest Long-Term Support (LTS) version of Deno.
        • If a new Deno LTS version is released, we will ensure compatibility with it.
        • If a Deno LTS version is deprecated, we will drop support for it in the next minor release.
      • Node.js Current Release: The latest Node.js release outside the LTS schedule.
        • If a new Node.js current release is available, we will ensure compatibility with it.
        • If a Node.js current release is deprecated, we will drop support for it in the next minor release.
    • Details:
      • Compatibility is maintained, and issues are addressed.

    Tier 3: Community Support

    • Definition: Environments that are not officially tested but are supported on a best-effort basis.
    • Environments:
      • Modern Browsers: Latest versions of major browsers, including:
        • Google Chrome
        • Mozilla Firefox
        • Microsoft Edge
        • Apple Safari
      • Deno Current Release: The latest Deno release outside the LTS schedule.
    • Details:
      • Installation methods are provided.
      • No automated testing is performed.
      • Issues reported by users will be addressed.
      • Targeting the latest versions ensures compatibility with modern web standards.
      • We will not actively test or maintain compatibility with older versions of browsers.

Patch Changes

  • #1363 9328563 Thanks @kamiazya! - Update Develop Environment

    • Drop turbo
    • Upgrade biome to 2.0
    • Upgrade TypeScript to 5.8
    • Upgrade Vite to 7.0
    • Upgrade Vitest to 3.2
    • Upgrade Peggy to 5.0 and drop ts-pegjs
    • Implement new E2E test workflow
  • #1363 9328563 Thanks @kamiazya! - ## Core Package TypeScript Type System Modernization

    🔧 FIXES

    GraphBase Class Type Compatibility

    Fixed GraphBase class type compatibility issues:

    • BREAKING INTERNAL: Updated GraphBase<T> to GraphBase<T, K> to properly implement GraphBaseModel<T, K> interface
      • First generic parameter T extends DotObjectType represents the object type ('Graph', 'Subgraph', etc.)
      • Second generic parameter K extends AttributeKey represents the attribute key constraints
    • Added missing $type property: Abstract $type property ensures proper implementation across subclasses
    • Enhanced type constraints: Proper separation between object types and attribute types for better type safety

    Updated class hierarchy:

    // Before
    export abstract class GraphBase<T extends AttributeKey>
      extends AttributesBase<T>
      implements GraphBaseModel<T>
    
    // After
    export abstract class GraphBase<T extends DotObjectType, K extends AttributeKey = AttributeKey>
      extends AttributesBase<K>
      implements GraphBaseModel<T, K>
    {
      public abstract get $type(): T;
    }

    Cascading updates to subclasses:

    • RootGraph: Updated to GraphBase<'Graph', GraphAttributeKey>
    • Subgraph: Updated to GraphBase<'Subgraph', SubgraphAttributeKey | ClusterSubgraphAttributeKey>
    • Test classes: Added required $type implementation

    🚀 IMPROVEMENTS

    Type Safety Enhancement

    • Eliminated type compatibility errors: All GraphBase-related type issues resolved using proper generic constraints
    • Maintained library TypeScript value: Strong typing preserved throughout the core type system
    • Interface-implementation alignment: GraphBase class now correctly implements GraphBaseModel interface requirements

    Enhanced Developer Experience

    • Better IntelliSense support: Improved autocomplete and type checking for core graph classes
    • Clearer error messages: More precise TypeScript errors when GraphBase subclasses are misused
    • Consistent type patterns: Unified approach to handling object types vs attribute types

    📊 TECHNICAL DETAILS

    Architecture Improvements

    • Generic type system enhancement: Proper separation of concerns between object types (DotObjectType) and attribute constraints (AttributeKey)
    • Abstract property enforcement: All GraphBase subclasses must properly implement $type property
    • Type parameter ordering: Consistent <ObjectType, AttributeType> pattern across the inheritance hierarchy

    Compatibility Notes

    • Runtime behavior unchanged: All functional behavior remains identical
    • API surface unchanged: No public API modifications for end users
    • Internal type system modernized: Enhanced type safety without breaking changes

    This update resolves TypeScript strict mode compilation errors in the core package while maintaining full backward compatibility and establishing a solid foundation for type-safe graph model development.

  • #1363 9328563 Thanks @kamiazya! - New GitHub Action main workflow and tests

  • Updated dependencies [9328563, 9328563, 9328563, 9328563, 9328563, 9328563]:

2.0.7

Patch Changes

2.0.6

Patch Changes

2.0.5

Patch Changes

2.0.4

Patch Changes

2.0.3

Patch Changes

2.0.2

Patch Changes

2.0.1

Patch Changes

2.0.0

It is part of the ts-graphviz library, which is split into modular packages to improve maintainability, flexibility, and ease of use.

This package contains the core implementation of models and functions provided to users for the ts-graphviz library.

Features

  • Graph, Node, and Edge model implementations
  • High-level APIs for creating and manipulating DOT language elements
  • Extensible design for custom implementations

Usage

Import the necessary classes and functions from the @ts-graphviz/core package:

import { Graph, Node, Edge } from "@ts-graphviz/core";

Use the imported items in your project to create and manipulate DOT language elements:

const graph = new Graph("G");
const nodeA = new Node("A", { label: "Node A" });
const nodeB = new Node("B", { label: "Node B" });
const edge = new Edge([nodeA, nodeB], { label: "A -> B" });

graph.addNode(nodeA);
graph.addNode(nodeB);
graph.addEdge(edge);

console.log(graph.toDot());