# diagrams-js > Draw cloud system architecture diagrams as code in TypeScript - [diagrams-js](/) ## playground - [Playground](/playground): Interactive diagrams-js playground ## search - [Search the documentation](/search) ## docs - [AI Guide](/docs/ai-guide): Guide for AI LLMs and agents using diagrams-js - [Credits](/docs/credits): Acknowledgments and credits - [Examples](/docs/getting-started/examples): Real-world architecture examples - [Installation](/docs/getting-started/installation): Installing diagrams-js in your project - [Quick Start](/docs/getting-started/quickstart): Create your first diagram in minutes - [API Reference](/docs/guides/api): Complete API documentation - [CLI](/docs/guides/cli): Using diagrams from the command line with @diagrams-js/cli - [Clusters](/docs/guides/clusters): Group nodes together with clusters - [Custom Nodes](/docs/guides/custom-nodes): Use your own icons and images - [Diagrams](/docs/guides/diagram): Understanding the Diagram class - [Diagram Diff](/docs/guides/diagram-diff): Compare two versions of a diagram visually to see what changed. The diff feature highlights added, removed, and modified elements with color-coded overlays in a side-by-side view. - [Edges](/docs/guides/edge): Connecting nodes with customized edges - [GitHub Action](/docs/guides/github-action): Using diagrams-js in GitHub Actions for CI/CD - [JSON Serialization](/docs/guides/json): Export and import diagrams as JSON for cloud architecture provisioning and tool integration - [Migration from Python diagrams](/docs/guides/migration): Migrate from Python diagrams to TypeScript - [Nodes](/docs/guides/node): Working with nodes and data flow - [Providers](/docs/guides/providers): Available cloud providers - [Rendering](/docs/guides/rendering): Render and export diagrams - [Alibaba Cloud](/docs/nodes/alibabacloud): Node types for Alibaba Cloud provider - [AWS](/docs/nodes/aws): Node types for Amazon Web Services provider - [Azure](/docs/nodes/azure): Node types for Microsoft Azure provider - [C4 Model](/docs/nodes/c4): Visualize software architecture using the C4 model - [DigitalOcean](/docs/nodes/digitalocean): Node types for DigitalOcean provider - [Elastic](/docs/nodes/elastic): Node types for Elastic Stack provider - [Firebase](/docs/nodes/firebase): Node types for Firebase provider - [GCP](/docs/nodes/gcp): Node types for Google Cloud Platform provider - [Generic](/docs/nodes/generic): Node types for generic/on-premise resources - [GIS](/docs/nodes/gis): Node types for GIS (Geographic Information Systems) provider - [IBM](/docs/nodes/ibm): Node types for IBM Cloud provider - [Kubernetes](/docs/nodes/k8s): Node types for Kubernetes provider - [OCI](/docs/nodes/oci): Node types for Oracle Cloud Infrastructure provider - [On-Premises](/docs/nodes/onprem): Node types for on-premises infrastructure - [OpenStack](/docs/nodes/openstack): Node types for OpenStack provider - [Outscale](/docs/nodes/outscale): Node types for Outscale provider - [Programming](/docs/nodes/programming): Node types for programming languages and frameworks - [SaaS](/docs/nodes/saas): Node types for Software as a Service providers - [Docker Compose Plugin](/docs/plugins/docker-compose): Import and export Docker Compose files with diagrams-js - [Kubernetes Plugin](/docs/plugins/kubernetes): Import and export Kubernetes YAML manifests with diagrams-js - [Plugin System Overview](/docs/plugins/overview): Extend diagrams-js with custom import/export formats, metadata providers, and hooks --- # Full Documentation Content Example: -- Select an example -- Share --- [Skip to main content](#__docusaurus_skipToContent_fallback) [![diagrams-js](/img/logo.svg)![diagrams-js](/img/logo.svg)](/) [**diagrams-js**](/)[Docs](/docs/getting-started/installation)[Examples](/docs/getting-started/examples)[Guides](/docs/guides/diagram)[Providers](/docs/guides/providers)[Playground](/playground)[Visual Editor](/visual-editor) [npm](https://www.npmjs.com/package/diagrams-js)[GitHub](https://github.com/diagrams-js/diagrams-js) Search # Search the documentation Type your search here Powered by[](https://www.algolia.com/) Docs * [Getting Started](/docs/getting-started/quickstart) * [Examples](/docs/getting-started/examples) * [API Reference](/docs/guides/diagram) For AI * [AI Guide](/docs/ai-guide) * [llms.txt](/llms.txt) * [llms-full.txt](/llms-full.txt) Community * [GitHub](https://github.com/diagrams-js/diagrams-js) * [𝕏 / Twitter](https://x.com/hatem_hosny_) More * [Playground](/playground) * [Visual Editor](/visual-editor) * [Sponsor 💚](https://github.com/sponsors/hatemhosny) Copyright © 2026 [Hatem Hosny](https://github.com/hatemhosny). MIT License. --- # AI Guide This guide is specifically designed for AI Large Language Models (LLMs) and autonomous agents to effectively use the diagrams-js library for generating cloud architecture diagrams. ## llms.txt[​](#llmstxt "Direct link to llms.txt") For optimal context when working with diagrams-js, use these specially formatted documentation files: **📄 [llms.txt](/llms.txt)** - Concise overview of the library, installation, basic usage, and key concepts **📄 [llms-full.txt](/llms-full.txt)** - Complete documentation including all guides, API reference, and examples These files are specifically structured for AI consumption with: * Clear API signatures and type definitions * Code examples with expected outputs * Provider reference lists * Best practices and common patterns See for more information about llms.txt standards. ## Skills[​](#skills "Direct link to Skills") diagrams-js provides skills for enhanced AI-assisted development. ### Installation for AI Agents[​](#installation-for-ai-agents "Direct link to Installation for AI Agents") Using [skills.sh](https://skills.sh/): ``` # Add skills into your project npx skills add hatemhosny/diagrams-js ``` Or using [`@tanstack/intent`](http://tanstack.com/intent/): ``` # Install skills into your project npx @tanstack/intent@latest install # Or use directly without installation npx @tanstack/intent@latest show diagrams-js/getting-started ``` ### Available Skills[​](#available-skills "Direct link to Available Skills") | Skill | Description | | ----------------------------------- | ------------------------------------------- | | `diagrams-js/getting-started` | Installation, first diagram, basic concepts | | `diagrams-js/diagram-configuration` | Direction, theme, curve style, attributes | | `diagrams-js/rendering-export` | SVG, PNG, JPG, DOT, data URLs | | `diagrams-js/provider-nodes` | 17+ providers, 2000+ node types | | `diagrams-js/custom-nodes` | External icons, URLs, data URLs | | `diagrams-js/node-connections` | to(), from(), with(), Edge styling | | `diagrams-js/clusters-grouping` | Clusters, nesting, organization | | `diagrams-js/browser-integration` | CDN, DOM, data URLs, downloads | | `diagrams-js/nodejs-integration` | File system, sharp, local icons | | `diagrams-js/python-migration` | Python to TypeScript conversion | ### Using Skills[​](#using-skills "Direct link to Using Skills") AI agents can load relevant skills automatically based on context: * Creating a new diagram → loads `getting-started` * Adding AWS/GCP/Azure nodes → loads `provider-nodes` * Connecting nodes with edges → loads `node-connections` * Rendering to different formats → loads `rendering-export` * Migrating from Python diagrams → loads `python-migration` ## Key Concepts for AI Agents[​](#key-concepts-for-ai-agents "Direct link to Key Concepts for AI Agents") ### 1. Diagram Structure[​](#1-diagram-structure "Direct link to 1. Diagram Structure") ``` import { Diagram } from "diagrams-js"; // Always create a diagram instance first const diagram = Diagram("Architecture Name", { direction: "TB", // Top-Bottom (or "LR" for Left-Right) }); ``` ### 2. Adding Nodes[​](#2-adding-nodes "Direct link to 2. Adding Nodes") Nodes can be added using the `add()` method: ``` import { Diagram, Node } from "diagrams-js"; const diagram = Diagram("Example"); // Basic node (no icon) const basicNode = diagram.add(Node("Label")); // Provider nodes (auto-include icons) import { EC2 } from "diagrams-js/aws/compute"; const server = diagram.add(EC2("Web Server")); ``` ### 3. Creating Connections[​](#3-creating-connections "Direct link to 3. Creating Connections") Use method chaining for connections: ``` import { Edge } from "diagrams-js"; // .to() - Forward direction (left to right) nodeA.to(nodeB); // Sequential connections nodeA.to(nodeB).to(nodeC); // Branching connections nodeA.to([nodeB, nodeC]); // Connect multiple nodes to one target const nodes = [nodeB, nodeC, nodeD]; nodes.forEach((n) => n.to(nodeA)); // .from() - Reverse direction (right to left) nodeB.from(nodeA); // .with() - Undirected/bidirectional (no arrows) nodeA.with(nodeB); // With custom styling using Edge nodeA.to(Edge({ color: "red", style: "dashed" }), nodeB); ``` ### 4. Rendering Output[​](#4-rendering-output "Direct link to 4. Rendering Output") ``` // Generate SVG const svg = await diagram.render(); // Use the SVG (save to file, display, etc.) ``` ## Common Patterns[​](#common-patterns "Direct link to Common Patterns") ### Web Application Architecture[​](#web-application-architecture "Direct link to Web Application Architecture") ``` import { Diagram } from "diagrams-js"; import { ALB } from "diagrams-js/aws/network"; import { EC2, AutoScaling } from "diagrams-js/aws/compute"; import { RDS } from "diagrams-js/aws/database"; import { S3 } from "diagrams-js/aws/storage"; const diagram = Diagram("Web App Architecture"); const lb = diagram.add(ALB("Load Balancer")); const web = diagram.add(EC2("Web Servers")); const db = diagram.add(RDS("Database")); const storage = diagram.add(S3("Assets")); lb.to(web); web.to([db, storage]); const svg = await diagram.render(); ``` ### Microservices Pattern[​](#microservices-pattern "Direct link to Microservices Pattern") ``` import { Diagram } from "diagrams-js"; import { ECS } from "diagrams-js/aws/compute"; const diagram = Diagram("Microservices"); // Group related services using clusters const apiCluster = diagram.cluster("API Gateway"); const auth = apiCluster.add(ECS("Auth Service")); const rateLimiter = apiCluster.add(ECS("Rate Limiter")); const servicesCluster = diagram.cluster("Services"); const userSvc = servicesCluster.add(ECS("User Service")); const orderSvc = servicesCluster.add(ECS("Order Service")); const paymentSvc = servicesCluster.add(ECS("Payment Service")); // Connect clusters auth.to([userSvc, orderSvc, paymentSvc]); const svg = await diagram.render(); ``` ## Provider Organization[​](#provider-organization "Direct link to Provider Organization") Cloud providers are organized hierarchically: ``` diagrams-js/ ├── aws/ │ ├── compute/ # EC2, Lambda, etc. │ ├── database/ # RDS, DynamoDB, etc. │ ├── storage/ # S3, EBS, etc. │ └── ... ├── azure/ │ ├── compute/ │ ├── database/ │ └── ... └── gcp/ ├── compute/ ├── database/ └── ... ``` ## Common Mistakes to Avoid[​](#common-mistakes-to-avoid "Direct link to Common Mistakes to Avoid") Here are critical mistakes that AI agents should avoid: ### Python Migration Issues[​](#python-migration-issues "Direct link to Python Migration Issues") When converting from Python diagrams: * ❌ **Context managers**: Python uses `with Diagram():`, TypeScript uses `const diagram = Diagram()` * ❌ **Operators**: Python uses `>>` / `<<` / `-`, TypeScript uses `.to()` / `.from()` / `.with()` * ❌ **Auto-registration**: Python auto-registers nodes, TypeScript requires `diagram.add()` * ❌ **Auto-render**: Python auto-renders on exit, TypeScript requires `await diagram.render()` ### Node Registration[​](#node-registration "Direct link to Node Registration") ``` // ❌ Wrong: Node not registered const web = EC2("Web Server"); web.to(db); // Error! // ✅ Correct: Explicit registration const web = diagram.add(EC2("Web Server")); web.to(db); // Works! ``` ### Async Rendering[​](#async-rendering "Direct link to Async Rendering") ``` // ❌ Wrong: Not awaiting const svg = diagram.render(); // ✅ Correct: Always await const svg = await diagram.render(); ``` ### Import Paths[​](#import-paths "Direct link to Import Paths") ``` // ❌ Wrong: Missing category import { EC2 } from "diagrams-js/aws"; // ✅ Correct: Include category import { EC2 } from "diagrams-js/aws/compute"; ``` ### Connection Direction[​](#connection-direction "Direct link to Connection Direction") ``` // For << arrow (db << api) // ❌ Wrong db.to(api); // ✅ Correct db.from(api); ``` ### Browser vs Node.js[​](#browser-vs-nodejs "Direct link to Browser vs Node.js") ``` // ❌ Wrong in browser import { writeFileSync } from "fs"; writeFileSync("out.svg", svg); // ✅ Correct in browser await diagram.save("diagram.svg"); ``` ## Best Practices for AI Generation[​](#best-practices-for-ai-generation "Direct link to Best Practices for AI Generation") 1. **Use descriptive node labels** that explain the component's role 2. **Group related nodes** using `Cluster` for better organization 3. **Set appropriate diagram direction** based on the layout needs 4. **Import only needed providers** to optimize bundle size 5. **Handle async operations** properly with `await diagram.render()` 6. **Always register nodes** with `diagram.add()` before connecting 7. **Load relevant skills** for enhanced guidance on specific tasks ## Environment Support[​](#environment-support "Direct link to Environment Support") * **Browsers**: Direct usage with ES modules * **Node.js/Deno/Bun**: Save SVG to files using
`await diagram.save("filename.svg", { format: "svg" }); // or "png"/"jpeg"` ## Resources[​](#resources "Direct link to Resources") * 📚 [Full Documentation](/docs/getting-started/installation) * 🔧 [API Reference](/docs/guides/diagram) * 🎨 [Provider List](/docs/guides/providers) * 🤖 [TanStack Intent Skills](https://github.com/diagrams-js/diagrams-js/blob/main/.agents/INTENT.md) - AI-assisted development * 📄 [llms.txt](/llms.txt) - Quick reference * 📄 [llms-full.txt](/llms-full.txt) - Complete docs --- # Credits diagrams-js is made possible thanks to these amazing projects and communities: ## Original Project[​](#original-project "Direct link to Original Project") **[diagrams](https://github.com/mingrammer/diagrams)** by [mingrammer](https://github.com/mingrammer) This project is a TypeScript port of the original Python diagrams library. We are grateful to mingrammer for creating such an elegant and powerful tool for drawing cloud architecture diagrams as code. ## Rendering Engine[​](#rendering-engine "Direct link to Rendering Engine") **[Graphviz](https://graphviz.org/)** The graph visualization software that powers the layout and rendering of all diagrams. Graphviz provides the sophisticated algorithms for positioning nodes and routing edges. **[viz-js](https://github.com/mdaines/viz-js)** by [mdaines](https://github.com/mdaines) A WebAssembly-based port of Graphviz for JavaScript. This enables diagrams-js to run entirely in the browser without requiring any server-side components. ## Icon Sets[​](#icon-sets "Direct link to Icon Sets") All node icons are from the original [diagrams](https://github.com/mingrammer/diagrams) library, which includes icons from various cloud providers and technology vendors. ## Community[​](#community "Direct link to Community") Thank you to all contributors and users who help improve diagrams-js through bug reports, feature requests, and pull requests. ## License[​](#license "Direct link to License") diagrams-js is released under the MIT License, same as the original diagrams library. --- # Examples Here are comprehensive examples demonstrating the capabilities of diagrams-js. info These examples are reproduced from the original [Python's Diagrams library](https://diagrams.mingrammer.com/docs/getting-started/examples) documentations. Live Demo For interactive examples with live rendered diagrams, check out the [playground](/playground). ## Grouped Workers on AWS[​](#grouped-workers-on-aws "Direct link to Grouped Workers on AWS") ``` import { Diagram } from "diagrams-js"; import { EC2 } from "diagrams-js/aws/compute"; import { RDS } from "diagrams-js/aws/database"; import { ELB } from "diagrams-js/aws/network"; const diagram = Diagram("Grouped Workers", { direction: "TB", }); const lb = diagram.add(ELB("lb")); const workers = [ diagram.add(EC2("worker1")), diagram.add(EC2("worker2")), diagram.add(EC2("worker3")), diagram.add(EC2("worker4")), diagram.add(EC2("worker5")), ]; const events = diagram.add(RDS("events")); lb.to(workers); workers.forEach((w) => w.to(events)); const svg = await diagram.render(); ``` ![Grouped Workers on AWS](/examples/example1-grouped-workers.svg) ## Clustered Web Services[​](#clustered-web-services "Direct link to Clustered Web Services") ``` import { Diagram } from "diagrams-js"; import { ECS } from "diagrams-js/aws/compute"; import { RDS, Elasticache } from "diagrams-js/aws/database"; import { ELB, Route53 } from "diagrams-js/aws/network"; const diagram = Diagram("Clustered Web Services"); const dns = diagram.add(Route53("dns")); const lb = diagram.add(ELB("lb")); const svcCluster = diagram.cluster("Services"); const svcGroup = [ svcCluster.add(ECS("web1")), svcCluster.add(ECS("web2")), svcCluster.add(ECS("web3")), ]; lb.to(svcGroup); const dbCluster = diagram.cluster("DB Cluster"); const dbPrimary = dbCluster.add(RDS("userdb")); const dbReplica = dbCluster.add(RDS("userdb ro")); dbPrimary.with(dbReplica); svcGroup.forEach((s) => s.to(dbPrimary)); const memcached = diagram.add(Elasticache("memcached")); svcGroup.forEach((s) => s.to(memcached)); dns.to(lb); const svg = await diagram.render(); ``` ![Clustered Web Services](/examples/example2-clustered-web-services.svg) ## Event Processing on AWS[​](#event-processing-on-aws "Direct link to Event Processing on AWS") ``` import { Diagram } from "diagrams-js"; import { ECS, EKS, Lambda } from "diagrams-js/aws/compute"; import { Redshift } from "diagrams-js/aws/database"; import { SQS } from "diagrams-js/aws/integration"; import { S3 } from "diagrams-js/aws/storage"; const diagram = Diagram("Event Processing"); const source = diagram.add(EKS("k8s source")); const store = diagram.add(S3("events store")); const dw = diagram.add(Redshift("analytics")); const flowsCluster = diagram.cluster("Event Flows"); const workersCluster = flowsCluster.cluster("Event Workers"); const workerNodes = [ workersCluster.add(ECS("worker1")), workersCluster.add(ECS("worker2")), workersCluster.add(ECS("worker3")), ]; source.to(workerNodes); const queue = flowsCluster.add(SQS("event queue")); workerNodes.forEach((w) => w.to(queue)); const procCluster = flowsCluster.cluster("Processing"); const handlers = [ procCluster.add(Lambda("proc1")), procCluster.add(Lambda("proc2")), procCluster.add(Lambda("proc3")), ]; queue.to(handlers); handlers.forEach((h) => { h.to(store); h.to(dw); }); const svg = await diagram.render(); ``` ![Event Processing on AWS](/examples/example3-event-processing.svg) ## Message Collecting System on GCP[​](#message-collecting-system-on-gcp "Direct link to Message Collecting System on GCP") ``` import { Diagram } from "diagrams-js"; import { BigQuery, Dataflow, PubSub } from "diagrams-js/gcp/analytics"; import { AppEngine, Functions } from "diagrams-js/gcp/compute"; import { Bigtable } from "diagrams-js/gcp/database"; import { IotCore } from "diagrams-js/gcp/iot"; import { Storage } from "diagrams-js/gcp/storage"; const diagram = Diagram("Message Collecting"); const pubsub = diagram.add(PubSub("pubsub")); const sourceCluster = diagram.cluster("Source of Data"); const sources = [ sourceCluster.add(IotCore("core1")), sourceCluster.add(IotCore("core2")), sourceCluster.add(IotCore("core3")), ]; sources.forEach((s) => s.to(pubsub)); const targetsCluster = diagram.cluster("Targets"); const flowCluster = targetsCluster.cluster("Data Flow"); const dataflow = flowCluster.add(Dataflow("data flow")); pubsub.to(dataflow); const lakeCluster = targetsCluster.cluster("Data Lake"); const bq = lakeCluster.add(BigQuery("bq")); const gcs = lakeCluster.add(Storage("storage")); dataflow.to([bq, gcs]); const eventCluster = targetsCluster.cluster("Event Driven"); const procCluster = eventCluster.cluster("Processing"); const engine = procCluster.add(AppEngine("engine")); const bigtable = procCluster.add(Bigtable("bigtable")); dataflow.to(engine).to(bigtable); const serverlessCluster = eventCluster.cluster("Serverless"); const func = serverlessCluster.add(Functions("func")); const appengine = serverlessCluster.add(AppEngine("appengine")); dataflow.to(func).to(appengine); const svg = await diagram.render(); ``` ![Message Collecting System on GCP](/examples/example4-message-collecting.svg) ## Exposed Pod with 3 Replicas on Kubernetes[​](#exposed-pod-with-3-replicas-on-kubernetes "Direct link to Exposed Pod with 3 Replicas on Kubernetes") ``` import { Diagram } from "diagrams-js"; import { HPA } from "diagrams-js/k8s/clusterconfig"; import { Deployment, Pod, ReplicaSet } from "diagrams-js/k8s/compute"; import { Ingress, Service } from "diagrams-js/k8s/network"; const diagram = Diagram("Exposed Pod with 3 Replicas"); const ingress = diagram.add(Ingress("domain.com")); const svc = diagram.add(Service("svc")); const pods = [diagram.add(Pod("pod1")), diagram.add(Pod("pod2")), diagram.add(Pod("pod3"))]; const rs = diagram.add(ReplicaSet("rs")); const dp = diagram.add(Deployment("dp")); const hpa = diagram.add(HPA("hpa")); ingress.to(svc); svc.to(pods); pods.forEach((p) => p.from(rs)); rs.from(dp); dp.from(hpa); const svg = await diagram.render(); ``` ![Exposed Pod with 3 Replicas](/examples/example5-k8s-exposed-pod.svg) ## Stateful Architecture on Kubernetes[​](#stateful-architecture-on-kubernetes "Direct link to Stateful Architecture on Kubernetes") ``` import { Diagram } from "diagrams-js"; import { Pod, StatefulSet } from "diagrams-js/k8s/compute"; import { Service } from "diagrams-js/k8s/network"; import { PV, PVC } from "diagrams-js/k8s/storage"; const diagram = Diagram("Stateful Architecture"); const appsCluster = diagram.cluster("Apps"); const svc = appsCluster.add(Service("svc")); const sts = appsCluster.add(StatefulSet("sts")); const pods = []; const pvcs = []; for (let i = 0; i < 3; i++) { const pod = appsCluster.add(Pod("pod")); const pvc = appsCluster.add(PVC("pvc")); pod.with(sts).with(pvc); svc.to(pod).to(pvc); pods.push(pod); pvcs.push(pvc); } const pv = diagram.add(PV("pv")); const sc = diagram.add(StorageClass("sc")); pvcs.forEach((pvc) => { pvc.from(pv); }); pv.from(sc); const svg = await diagram.render(); ``` ![Stateful Architecture](/examples/example6-k8s-stateful.svg) ## Advanced Web Service with On-Premises[​](#advanced-web-service-with-on-premises "Direct link to Advanced Web Service with On-Premises") ``` import { Diagram } from "diagrams-js"; import { Spark } from "diagrams-js/onprem/analytics"; import { Server } from "diagrams-js/onprem/compute"; import { PostgreSQL } from "diagrams-js/onprem/database"; import { Redis } from "diagrams-js/onprem/inmemory"; import { Fluentd } from "diagrams-js/onprem/aggregator"; import { Grafana, Prometheus } from "diagrams-js/onprem/monitoring"; import { Nginx } from "diagrams-js/onprem/network"; import { Kafka } from "diagrams-js/onprem/queue"; const diagram = Diagram("Advanced Web Service with On-Premises"); const ingress = diagram.add(Nginx("ingress")); const metrics = diagram.add(Prometheus("metric")); const grafana = diagram.add(Grafana("monitoring")); metrics.from(grafana); const serviceCluster = diagram.cluster("Service Cluster"); const grpcsvc = [ serviceCluster.add(Server("grpc1")), serviceCluster.add(Server("grpc2")), serviceCluster.add(Server("grpc3")), ]; const sessionsCluster = diagram.cluster("Sessions HA"); const sessionPrimary = sessionsCluster.add(Redis("session")); const sessionReplica = sessionsCluster.add(Redis("replica")); sessionPrimary.with(sessionReplica); sessionReplica.from(metrics); grpcsvc.forEach((svc) => svc.to(sessionPrimary)); const dbCluster = diagram.cluster("Database HA"); const dbPrimary = dbCluster.add(PostgreSQL("users")); const dbReplica = dbCluster.add(PostgreSQL("replica")); dbPrimary.with(dbReplica); dbReplica.from(metrics); grpcsvc.forEach((svc) => svc.to(dbPrimary)); const aggregator = diagram.add(Fluentd("logging")); const kafka = diagram.add(Kafka("stream")); const spark = diagram.add(Spark("analytics")); aggregator.to(kafka).to(spark); ingress.to(grpcsvc); grpcsvc.forEach((svc) => svc.to(aggregator)); const svg = await diagram.render(); ``` ![Advanced Web Service with On-Premises](/examples/example7-onprem-advanced.svg) ## Advanced Web Service with On-Premises (with colors and labels)[​](#advanced-web-service-with-on-premises-with-colors-and-labels "Direct link to Advanced Web Service with On-Premises (with colors and labels)") ``` import { Diagram, Edge } from "diagrams-js"; import { Spark } from "diagrams-js/onprem/analytics"; import { Server } from "diagrams-js/onprem/compute"; import { PostgreSQL } from "diagrams-js/onprem/database"; import { Redis } from "diagrams-js/onprem/inmemory"; import { Fluentd } from "diagrams-js/onprem/aggregator"; import { Grafana, Prometheus } from "diagrams-js/onprem/monitoring"; import { Nginx } from "diagrams-js/onprem/network"; import { Kafka } from "diagrams-js/onprem/queue"; const diagram = Diagram("Advanced Web Service with On-Premises (colored)"); const ingress = diagram.add(Nginx("ingress")); const metrics = diagram.add(Prometheus("metric")); const grafana = diagram.add(Grafana("monitoring")); grafana.to(Edge({ color: "firebrick", style: "dashed" }), metrics); const serviceCluster = diagram.cluster("Service Cluster"); const grpcsvc = [ serviceCluster.add(Server("grpc1")), serviceCluster.add(Server("grpc2")), serviceCluster.add(Server("grpc3")), ]; const sessionsCluster = diagram.cluster("Sessions HA"); const sessionPrimary = sessionsCluster.add(Redis("session")); const sessionReplica = sessionsCluster.add(Redis("replica")); sessionPrimary.with(Edge({ color: "brown", style: "dashed" }), sessionReplica); sessionReplica.from(Edge({ label: "collect" }), metrics); grpcsvc.forEach((svc) => svc.to(Edge({ color: "brown" }), sessionPrimary)); const dbCluster = diagram.cluster("Database HA"); const dbPrimary = dbCluster.add(PostgreSQL("users")); const dbReplica = dbCluster.add(PostgreSQL("replica")); dbPrimary.with(Edge({ color: "brown", style: "dotted" }), dbReplica); dbReplica.from(Edge({ label: "collect" }), metrics); grpcsvc.forEach((svc) => svc.to(Edge({ color: "black" }), dbPrimary)); const aggregator = diagram.add(Fluentd("logging")); const kafka = diagram.add(Kafka("stream")); const spark = diagram.add(Spark("analytics")); aggregator.to(Edge({ label: "parse" }), kafka); kafka.to(Edge({ color: "black", style: "bold" }), spark); grpcsvc.forEach((svc) => { ingress.to(Edge({ color: "darkgreen", forward: true, reverse: true }), svc); }); grpcsvc.forEach((svc) => svc.to(Edge({ color: "darkorange" }), aggregator)); const svg = await diagram.render(); ``` ![Advanced Web Service with On-Premises (with colors and labels)](/examples/example8-onprem-advanced-colors.svg) ## RabbitMQ Consumers with Custom Nodes[​](#rabbitmq-consumers-with-custom-nodes "Direct link to RabbitMQ Consumers with Custom Nodes") ``` import { Diagram, Custom, Iconify } from "diagrams-js"; import { Pod } from "diagrams-js/k8s/compute"; const diagram = Diagram("Broker Consumers"); const consumersCluster = diagram.cluster("Consumers"); const consumers = [ consumersCluster.add(Pod("worker")), consumersCluster.add(Pod("worker")), consumersCluster.add(Pod("worker")), ]; const queue = diagram.add( // Use a custom icon from a URL Custom("Message queue", "https://jpadilla.github.io/rabbitmqapp/assets/img/icon.png", { width: "1.0", }), ); // Use Iconify icons const database = diagram.add(Iconify("Database", "logos:aws-aurora")); queue.to(consumers); consumers.forEach((consumer) => consumer.to(database)); const svg = await diagram.render(); ``` ![RabbitMQ Consumers with Custom Nodes](/examples/example9-custom-nodes.svg) ## Docker Compose Plugin Example[​](#docker-compose-plugin-example "Direct link to Docker Compose Plugin Example") This example demonstrates using the Docker Compose plugin. ``` import { Diagram } from "diagrams-js"; import { dockerComposePlugin } from "@diagrams-js/plugin-docker-compose"; const diagram = Diagram("E-commerce Application"); // Register the plugin instance await diagram.registerPlugins([dockerComposePlugin]); // Import from Docker Compose YAML const composeYaml = ` version: "3.8" name: ecommerce-app services: frontend: image: nginx:alpine ports: - "80:80" depends_on: - api api: image: node:18 ports: - "3000:3000" depends_on: - db - cache db: image: postgres:15 environment: POSTGRES_DB: ecommerce volumes: - pgdata:/var/lib/postgresql/data cache: image: redis:7-alpine volumes: pgdata: `; await diagram.import(composeYaml, "docker-compose"); // Render the diagram const svg = await diagram.render(); ``` ![Docker Compose Plugin Example](/examples/ecommerce-app.svg) Learn More For a comprehensive guide on creating plugins, check out the [Plugin System](/docs/plugins/overview) documentation. ## Next Steps[​](#next-steps "Direct link to Next Steps") * Explore [all providers](/docs/guides/providers) and their available nodes * Read the [complete API reference](/docs/guides/diagram) * Try the [playground](/playground) for interactive examples --- # Installation ## Node.js[​](#nodejs "Direct link to Node.js") Install [`diagrams-js`](https://www.npmjs.com/package/diagrams-js) using your preferred package manager: * npm * yarn * pnpm * bun ``` npm install diagrams-js ``` ``` yarn add diagrams-js ``` ``` pnpm add diagrams-js ``` ``` bun add diagrams-js ``` Bun Version Bun 1.3.0+ is required for diagrams-js to work properly due to WebAssembly support improvements. ### Optional Dependencies[​](#optional-dependencies "Direct link to Optional Dependencies") [Rendering](/docs/guides/rendering) SVG does not require any additional packages. However, for PNG and JPG rendering in Node.js, the package `sharp` is required: * npm * yarn * pnpm * bun ``` npm install sharp ``` ``` yarn add sharp ``` ``` pnpm add sharp ``` ``` bun add sharp ``` ## Browser Usage[​](#browser-usage "Direct link to Browser Usage") ### Using a Bundler[​](#using-a-bundler "Direct link to Using a Bundler") Install via npm and import: ``` import { Diagram } from "diagrams-js"; import { EC2 } from "diagrams-js/aws/compute"; ``` ### Using CDN[​](#using-cdn "Direct link to Using CDN") ``` ``` ### Using CDN with Import Map[​](#using-cdn-with-import-map "Direct link to Using CDN with Import Map") You can use import maps to enable bare module imports while loading from a CDN: ``` ``` Import Maps Import maps allow you to use bare module specifiers (like `diagrams-js/aws/compute`) instead of full URLs, making your code cleaner and more portable between bundler and CDN environments. ## Next Steps[​](#next-steps "Direct link to Next Steps") * Follow the [Quick Start guide](/docs/getting-started/quickstart) to create your first diagram * Explore the [Examples](/docs/getting-started/examples) for real-world use cases * Check out the [Node Reference](/docs/guides/providers) for all available providers and services --- # Quick Start Get started with diagrams-js in just a few lines of code. ## Basic Diagram[​](#basic-diagram "Direct link to Basic Diagram") Create a simple diagram with nodes and connections: ``` import { Diagram, Node } from "diagrams-js"; // Create a diagram const diagram = Diagram("My First Diagram", { // Diagram options direction: "TB", // Top to Bottom }); // Add nodes const web = diagram.add(Node("Web Server")); const app = diagram.add(Node("App Server")); const db = diagram.add(Node("Database")); // Connect them web.to(app).to(db); // Render to SVG const svg = await diagram.render(); // Clean up ``` ![Basic Diagram](/examples/quickstart-basic.svg) ## Using Cloud Providers[​](#using-cloud-providers "Direct link to Using Cloud Providers") Import nodes from cloud providers to get automatic icons: ``` import { Diagram } from "diagrams-js"; import { EC2, Lambda } from "diagrams-js/aws/compute"; import { RDS } from "diagrams-js/aws/database"; import { S3 } from "diagrams-js/aws/storage"; import { ALB } from "diagrams-js/aws/network"; const diagram = Diagram("AWS Architecture", { direction: "TB" }); // Create nodes with icons const lb = diagram.add(ALB("Load Balancer")); const web = diagram.add(EC2("Web Server")); const api = diagram.add(Lambda("API")); const db = diagram.add(RDS("Database")); const storage = diagram.add(S3("Storage")); // Connect them lb.to(web).to(api); api.to([db, storage]); // Render to SVG const svg = await diagram.render(); ``` ![AWS Architecture Example](/examples/quickstart-cloud.svg) ## Browser Integration[​](#browser-integration "Direct link to Browser Integration") Display the diagram directly in the browser: ```
``` ## Node.js Usage[​](#nodejs-usage "Direct link to Node.js Usage") Save diagrams to files in Node.js: ``` import { Diagram } from "diagrams-js"; import { EC2 } from "diagrams-js/aws/compute"; import { writeFileSync } from "fs"; const diagram = Diagram("My Diagram"); diagram.add(EC2("Server")); const svg = await diagram.render(); writeFileSync("diagram.svg", svg); ``` ## Key Concepts[​](#key-concepts "Direct link to Key Concepts") 1. **Diagram**: The container for your architecture diagram 2. **Nodes**: Components like servers, databases, and services 3. **Connections**: Relationships between nodes using `.to()`, `.from()`, and `.with()` 4. **Providers**: Cloud service categories (AWS, Azure, GCP, etc.) ## Next Steps[​](#next-steps "Direct link to Next Steps") * Learn about [Diagrams](/docs/guides/diagram) in detail * Explore [Nodes](/docs/guides/node) and connections * See [all providers](/docs/guides/providers) and their services * Check out [complete examples](/docs/getting-started/examples) --- # API Reference ## Core Functions[​](#core-functions "Direct link to Core Functions") ### Diagram(name, options?)[​](#diagramname-options "Direct link to Diagram(name, options?)") Creates a new diagram. **Parameters:** * `name` (string): The diagram name (used for labeling and default filename) * `options` (DiagramOptions, optional): Configuration options **Returns:** Diagram instance ``` const diagram = Diagram("My Diagram", { direction: "LR", theme: "neutral", }); ``` **DiagramOptions:** | Property | Type | Default | Description | | ------------ | --------------------------------------------- | ------------------- | ---------------------------------- | | `name` | string | Same as first param | Diagram display name | | `filename` | string | Lowercase name | Output filename | | `direction` | "TB" \| "BT" \| "LR" \| "RL" | "LR" | Layout direction | | `curvestyle` | "ortho" \| "curved" \| "spline" \| "polyline" | "ortho" | Edge curve style | | `theme` | ThemeName | "neutral" | Color theme | | `autolabel` | boolean | false | Auto-prefix labels with class name | | `strict` | boolean | false | Use strict graph mode | | `graphAttr` | Record\ | | Custom graph attributes | | `nodeAttr` | Record\ | | Custom node attributes | | `edgeAttr` | Record\ | | Custom edge attributes | **Methods:** #### diagram.add(node)[​](#diagramaddnode "Direct link to diagram.add(node)") Add a node to the diagram. ``` const server = diagram.add(EC2("Web Server")); ``` #### diagram.cluster(label)[​](#diagramclusterlabel "Direct link to diagram.cluster(label)") Create a cluster (subgraph) for grouping nodes. ``` const cluster = diagram.cluster("Services"); const node = cluster.add(EC2("web")); ``` #### diagram.render(options?)[​](#diagramrenderoptions "Direct link to diagram.render(options?)") Render the diagram to a string or binary format. ``` // SVG (default) const svg = await diagram.render(); // PNG const png = await diagram.render({ format: "png" }); // DOT const dot = await diagram.render({ format: "dot" }); // As data URL (for direct use in browsers) const dataUrl = await diagram.render({ dataUrl: true }); // Returns: data:image/svg+xml;base64,PHN2Zy4uLg== // PNG as data URL const pngDataUrl = await diagram.render({ format: "png", dataUrl: true }); // Returns: data:image/png;base64,iVBORw0KGgo... ``` **RenderOptions:** | Property | Type | Default | Description | | ------------- | -------------------------------- | ------- | ----------------------- | | `format` | "svg" \| "png" \| "jpg" \| "dot" | "svg" | Output format | | `width` | number | Auto | Output width (PNG/JPG) | | `height` | number | Auto | Output height (PNG/JPG) | | `scale` | number | 2 | Scale factor (PNG/JPG) | | `injectIcons` | boolean | true | Auto-inject node icons | | `dataUrl` | boolean | false | Return as data URL | #### diagram.save(filepath?)[​](#diagramsavefilepath "Direct link to diagram.save(filepath?)") Save the diagram to a file. ``` await diagram.save("diagram.svg"); await diagram.save("diagram.png"); ``` ### Node(label, options?)[​](#nodelabel-options "Direct link to Node(label, options?)") Creates a generic node. Usually you use provider-specific node functions instead. ``` import { Node } from "diagrams-js"; const node = diagram.add(Node("My Node")); ``` **Node Methods:** #### node.to(target)[​](#nodetotarget "Direct link to node.to(target)") Create a forward connection (left to right). ``` web.to(api); web.to([api1, api2]); // Multiple targets ``` #### node.from(source)[​](#nodefromsource "Direct link to node.from(source)") Create a reverse connection (right to left). ``` db.from(api); db.from([api1, api2]); // Multiple sources ``` #### node.with(target)[​](#nodewithtarget "Direct link to node.with(target)") Create an undirected connection (no arrows). ``` primary.with(replica); ``` ### Edge(options?)[​](#edgeoptions "Direct link to Edge(options?)") Creates an edge with custom properties. ``` import { Edge } from "diagrams-js"; // Simple edge web.to(Edge({ color: "red" }), db); // With multiple properties web.to( Edge({ label: "data", color: "blue", style: "dashed", }), db, ); ``` **EdgeOptions:** | Property | Type | Description | | --------------- | ------- | ---------------------------------------- | | `label` | string | Edge label text | | `color` | string | Edge color | | `style` | string | Line style (solid, dashed, dotted, bold) | | `forward` | boolean | Show forward arrow | | `reverse` | boolean | Show reverse arrow | | `[key: string]` | any | Any Graphviz edge attribute | ### Custom(label, iconUrl, options?)[​](#customlabel-iconurl-options "Direct link to Custom(label, iconUrl, options?)") Creates a node with a custom icon. ``` import { Custom } from "diagrams-js"; // From URL const node = diagram.add(Custom("Service", "https://example.com/icon.png")); // From data URL const node2 = diagram.add(Custom("Local", "data:image/png;base64,...")); ``` **Parameters:** * `label` (string): Node label * `iconUrl` (string): Icon URL or data URL * `options` (object, optional): Additional node options ## Provider Imports[​](#provider-imports "Direct link to Provider Imports") ### AWS[​](#aws "Direct link to AWS") ``` import { EC2, Lambda, ECS } from "diagrams-js/aws/compute"; import { RDS, DynamoDB } from "diagrams-js/aws/database"; import { S3 } from "diagrams-js/aws/storage"; import { ALB, Route53 } from "diagrams-js/aws/network"; ``` ### Azure[​](#azure "Direct link to Azure") ``` import { VM } from "diagrams-js/azure/compute"; import { SQLDatabase } from "diagrams-js/azure/databases"; ``` ### GCP[​](#gcp "Direct link to GCP") ``` import { GCE, GKE } from "diagrams-js/gcp/compute"; import { CloudSQL } from "diagrams-js/gcp/database"; import { CloudStorage } from "diagrams-js/gcp/storage"; ``` ### Kubernetes[​](#kubernetes "Direct link to Kubernetes") ``` import { Pod, Deployment } from "diagrams-js/k8s/compute"; import { Service, Ingress } from "diagrams-js/k8s/network"; ``` See [Providers](/docs/guides/providers) for complete list. ## Utility Functions[​](#utility-functions "Direct link to Utility Functions") ### setIconBaseDir(dir)[​](#seticonbasedirdir "Direct link to setIconBaseDir(dir)") Set the base directory for loading icons in Node.js. ``` import { setIconBaseDir } from "diagrams-js"; setIconBaseDir("./icons"); ``` ### getIconBaseDir()[​](#geticonbasedir "Direct link to getIconBaseDir()") Get the current icon base directory. ``` import { getIconBaseDir } from "diagrams-js"; const dir = getIconBaseDir(); ``` ## Type Exports[​](#type-exports "Direct link to Type Exports") ``` import type { DiagramOptions, EdgeOptions, NodeOptions, ThemeName, ThemeConfig } from "diagrams-js"; ``` ## Complete Example[​](#complete-example "Direct link to Complete Example") ``` import { Diagram, Edge, Custom, type DiagramOptions } from "diagrams-js"; import { EC2 } from "diagrams-js/aws/compute"; import { RDS } from "diagrams-js/aws/database"; const options: DiagramOptions = { direction: "TB", theme: "pastel", graphAttr: { fontsize: "20", }, }; const diagram = Diagram("Architecture", options); const web = diagram.add(EC2("Web")); const db = diagram.add(RDS("DB")); const cache = diagram.add(Custom("Cache", "https://example.com/redis.png")); web.to(Edge({ color: "blue" }), db); web.to(Edge({ style: "dashed" }), cache); // Render as SVG string const svg = await diagram.render(); // Or render as data URL for direct use const dataUrl = await diagram.render({ dataUrl: true }); // Display in browser const img = document.createElement("img"); img.src = dataUrl; document.body.appendChild(img); await diagram.save("architecture.svg"); ``` --- # CLI Use diagrams-js from the command line with `@diagrams-js/cli`. Render diagrams, import/export with plugins, generate diffs, scaffold new files, and watch for changes. ## Installation[​](#installation "Direct link to Installation") Install globally with `npm`: ``` npm install -g @diagrams-js/cli # then run `diagrams` diagrams render diagram.ts ``` Alternatively, install locally in your project: ``` npm install @diagrams-js/cli # then run `npx diagrams` npx diagrams render diagram.ts ``` Or use directly with `npx`: ``` npx @diagrams-js/cli render diagram.ts ``` ## Commands[​](#commands "Direct link to Commands") ### `render`[​](#render "Direct link to render") Render a diagram file to SVG, PNG, JPG, DOT, or JSON. Also supports importing from external formats (Docker Compose, Kubernetes, etc.) via plugins when given `.yaml` or `.yml` files. Can also read from stdin or inline data. Given these examples: diagram.ts The diagram must be the default export: ``` import { Diagram } from "diagrams-js"; import { EC2 } from "diagrams-js/aws/compute"; import { RDS } from "diagrams-js/aws/database"; import { S3 } from "diagrams-js/aws/storage"; const diagram = Diagram("My Architecture"); const web = diagram.add(EC2("Web Server")); const db = diagram.add(RDS("Database")); const storage = diagram.add(S3("Storage")); web.to(db); web.to(storage); // the diagram must be the default export export default diagram; ``` diagram.json ``` { "nodes": [ { "id": "moq10984_mtpsupb74", "label": "Web Server", "provider": "aws", "type": "compute", "resource": "EC2" }, { "id": "moq10984_f5m7biyus", "label": "Database", "provider": "aws", "type": "database", "resource": "RDS" }, { "id": "moq10984_2ushtc3hs", "label": "Storage", "provider": "aws", "type": "storage", "resource": "SimpleStorageServiceS3" } ], "name": "My Architecture", "edges": [ { "from": "moq10984_mtpsupb74", "to": "moq10984_f5m7biyus" }, { "from": "moq10984_mtpsupb74", "to": "moq10984_2ushtc3hs" } ] } ``` ``` # Render diagram source to SVG (default: .svg) diagrams render diagram.ts # creates diagram.svg # Also supports JSON diagrams render diagram.json # Render to PNG diagrams render diagram.ts -o diagram.png # Render with theme and direction diagrams render diagram.ts -f svg -t dark -d LR -o out.svg # Render to JSON diagrams render diagram.ts -f json # Import Docker Compose and render to SVG diagrams render docker-compose.yml # Import Kubernetes manifest and render to PNG diagrams render k8s-deployment.yaml -o architecture.png # Output to stdout instead of file diagrams render diagram.ts --stdout # Write to file AND output to stdout diagrams render diagram.ts -o out.svg --stdout # Render from stdin (pipe JSON or SVG) cat diagram.json | diagrams render - -o out.svg ``` **Supported input sources:** * File: `.ts`, `.js`, `.mjs`, `.json`, `.svg`, `.yaml`, `.yml` * Stdin: pass `-` as the file argument **Supported output formats:** `svg`, `png`, `jpg`, `dot`, `json` **Options:** | Option | Description | | ----------------------- | --------------------------------------------------------------- | | `-o, --output ` | Output file path (default: same name as input file with `.svg`) | | `--stdout` | Output to stdout (in addition to `--output` if both are set) | | `-f, --format ` | Output format: `svg`, `png`, `jpg`, `dot`, `json` | | `-p, --plugin ` | Plugin to use for importing (auto-detected) | | `-t, --theme ` | Color theme | | `-d, --direction ` | Layout direction: `TB`, `BT`, `LR`, `RL` | | `--curve-style