Diagram as Code
Diagram as Code (DaC) brings the same principles of Infrastructure as Code (IaC) to visual documentation. Instead of manually drawing diagrams in tools like Lucidchart, draw.io or Visio, you describe them in text like Mermaid. That description generates consistent, up-to-date diagrams.
Why dinghy diagram
Compare to existing text based diagram such as Mermaid, dinghy provide a programmable diagrams which turn your data and system live information into generative, data-driven, reusable diagrams. They become living views of systems that evolve with the code and infrastructure.
Powered by React
Dinghy uses React as its templating engine. React is a widely adopted framework for transforming data models into various views, from web and native apps to hardware interfaces. While many diagramming project rely on React as a development framework, Dinghy takes a different approach — it’s built as an end-user tool, designed to work out of the box with zero configuration.
Shape component
All visual object are based on Shape. A shape could be either entity or container. When there is no visable children, a shape becomes an entity, othereise it's a container.
import { Shape } from "@dinghy/base-components";
export default function App() {
return (
<Shape _title="Basic shapes">
<Shape _title="Container">
<Shape>Entity</Shape>
</Shape>
</Shape>
);
}

Attributes
You might noticed all attribute so far are all start with _ (underscore).
That's right, the attribute name convention is that all dinghy internal attributes are
prefixed with underscore. None underscore attribute are reserved for
Infrastructure as Code data model.
Dependency component
Dependency is used to express the relationships between shapes.
You may use the Depenceny component directly for advanced styling or just use
_dependsOn or _dependsBy attribute to draw the relationship. The value could
be single string or array of strings.
The string target will be match following attributes in order:
_idattribute_titleattribute- Tag of target component
import { Dependency, Shape } from "@dinghy/base-components";
export default function App() {
return (
<Shape _title="Dependency example">
<Shape _dependsOn="B">A</Shape>
<Shape _title="B">
<Dependency _target="C" />
</Shape>
<Shape>C</Shape>
</Shape>
);
}

draw.io elements
You can import draw.io libary elements into your diagram to enhance its appearance.
import { Shape } from "@dinghy/base-components";
import { Client } from "@dinghy/diagrams/entitiesAwsGeneralResources";
import { AwsCloud } from "@dinghy/diagrams/containersAwsGroups";
import { PostgreSqlInstance } from "@dinghy/diagrams/entitiesAwsDatabase";
import { Activity } from "@dinghy/diagrams/dependenciesUml25";
export default function App() {
return (
<Shape _title="draw.io example">
<Client>
<Activity _target="Database" />
</Client>
<AwsCloud>
<Database />
</AwsCloud>
</Shape>
);
}
const Database = (props: any) => <PostgreSqlInstance {...props} />;

Composites diagrams
We intend to build out standard set of common diagram capability so ready to use by provide simple data structure.
You may found out the list of such composites in references section.
The Runtime sequence diagram of the Dinghy Architecture was defined as code below:
import { SequenceDiagram } from "@dinghy/diagrams/sequenceDiagram";
import { Shape } from "@dinghy/base-components";
const DockerIcon = (props: any) => (
<Shape
_image="data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%20viewBox%3D%220%200%20122.88%2088.17%22%20style%3D%22enable-background%3Anew%200%200%20122.88%2088.17%22%20xml%3Aspace%3D%22preserve%22%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E.st0%7Bfill%3A%230091E2%3B%7D%3C%2Fstyle%3E%3Cg%3E%3Cpath%20class%3D%22st0%22%20d%3D%22M121.68%2C33.34c-0.34-0.28-3.42-2.62-10.03-2.62c-1.71%2C0-3.48%2C0.17-5.19%2C0.46c-1.25-8.72-8.49-12.94-8.78-13.16%20l-1.77-1.03l-1.14%2C1.65c-1.42%2C2.22-2.51%2C4.73-3.13%2C7.29c-1.2%2C4.96-0.46%2C9.63%2C2.05%2C13.62c-3.02%2C1.71-7.92%2C2.11-8.95%2C2.17l-80.93%2C0%20c-2.11%2C0-3.82%2C1.71-3.82%2C3.82c-0.11%2C7.07%2C1.08%2C14.13%2C3.53%2C20.8c2.79%2C7.29%2C6.95%2C12.71%2C12.31%2C16.01c6.04%2C3.7%2C15.9%2C5.81%2C27.01%2C5.81%20c5.01%2C0%2C10.03-0.46%2C14.99-1.37c6.9-1.25%2C13.51-3.65%2C19.6-7.12c5.02-2.91%2C9.52-6.61%2C13.34-10.94c6.44-7.24%2C10.26-15.33%2C13.05-22.51%20c0.4%2C0%2C0.74%2C0%2C1.14%2C0c7.01%2C0%2C11.34-2.79%2C13.73-5.19c1.6-1.48%2C2.79-3.31%2C3.65-5.36l0.51-1.48L121.68%2C33.34L121.68%2C33.34z%20M71.59%2C39.38h10.83c0.51%2C0%2C0.97-0.4%2C0.97-0.97v-9.69c0-0.51-0.4-0.97-0.97-0.97l0%2C0l-10.83%2C0c-0.51%2C0-0.97%2C0.4-0.97%2C0.97l0%2C0v9.69%20C70.68%2C38.98%2C71.08%2C39.38%2C71.59%2C39.38L71.59%2C39.38z%20M56.49%2C11.63h10.83c0.51%2C0%2C0.97-0.4%2C0.97-0.97V0.97c0-0.51-0.46-0.97-0.97-0.97%20L56.49%2C0c-0.51%2C0-0.97%2C0.4-0.97%2C0.97l0%2C0v9.69C55.52%2C11.17%2C55.97%2C11.63%2C56.49%2C11.63L56.49%2C11.63z%20M56.49%2C25.53h10.83%20c0.51%2C0%2C0.97-0.46%2C0.97-0.97v-9.69c0-0.51-0.46-0.97-0.97-0.97H56.49c-0.51%2C0-0.97%2C0.4-0.97%2C0.97l0%2C0v9.69%20C55.52%2C25.08%2C55.97%2C25.53%2C56.49%2C25.53L56.49%2C25.53z%20M41.5%2C25.53h10.83c0.51%2C0%2C0.97-0.46%2C0.97-0.97v-9.69c0-0.51-0.4-0.97-0.97-0.97%20l0%2C0H41.5c-0.51%2C0-0.97%2C0.4-0.97%2C0.97l0%2C0v9.69C40.53%2C25.08%2C40.93%2C25.53%2C41.5%2C25.53L41.5%2C25.53z%20M26.28%2C25.53h10.83%20c0.51%2C0%2C0.97-0.46%2C0.97-0.97v-9.69c0-0.51-0.4-0.97-0.97-0.97l0%2C0H26.28c-0.51%2C0-0.97%2C0.4-0.97%2C0.97v9.69%20C25.37%2C25.08%2C25.77%2C25.53%2C26.28%2C25.53L26.28%2C25.53z%20M56.49%2C39.38h10.83c0.51%2C0%2C0.97-0.4%2C0.97-0.97v-9.69c0-0.51-0.4-0.97-0.97-0.97%20l0%2C0l-10.83%2C0c-0.51%2C0-0.97%2C0.4-0.97%2C0.97l0%2C0v9.69C55.52%2C38.98%2C55.97%2C39.38%2C56.49%2C39.38L56.49%2C39.38L56.49%2C39.38z%20M41.5%2C39.38%20h10.83c0.51%2C0%2C0.97-0.4%2C0.97-0.97l0%2C0v-9.69c0-0.51-0.4-0.97-0.97-0.97l0%2C0l-10.83%2C0c-0.51%2C0-0.97%2C0.4-0.97%2C0.97l0%2C0v9.69%20C40.53%2C38.98%2C40.93%2C39.38%2C41.5%2C39.38L41.5%2C39.38L41.5%2C39.38z%20M26.28%2C39.38h10.83c0.51%2C0%2C0.97-0.4%2C0.97-0.97l0%2C0v-9.69%20c0-0.51-0.4-0.97-0.97-0.97l0%2C0l-10.83%2C0c-0.51%2C0-0.97%2C0.4-0.97%2C0.97v9.69C25.37%2C38.98%2C25.77%2C39.38%2C26.28%2C39.38L26.28%2C39.38z%20M11.35%2C39.38h10.83c0.51%2C0%2C0.97-0.4%2C0.97-0.97l0%2C0v-9.69c0-0.51-0.4-0.97-0.97-0.97l0%2C0l-10.83%2C0c-0.51%2C0-0.97%2C0.4-0.97%2C0.97l0%2C0%20v9.69C10.44%2C38.98%2C10.84%2C39.38%2C11.35%2C39.38L11.35%2C39.38L11.35%2C39.38z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"
{...props}
/>
);
const CliIcon = (props: any) => (
<Shape
_image="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20fill%3D%22none%22%20viewBox%3D%22-0.75%20-0.75%2016%2016%22%20stroke%3D%22%23000000%22%20aria-hidden%3D%22true%22%20id%3D%22Command-Line--Streamline-Heroicons-Outline%22%20height%3D%2216%22%20width%3D%2216%22%3E%3Cdesc%3E%20%20%20%20Command%20Line%20Streamline%20Icon%3A%20https%3A%2F%2Fstreamlinehq.com%20%20%3C%2Fdesc%3E%3Cpath%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20d%3D%22m4.078125%204.53125%201.8125%201.359375%20-1.8125%201.359375m2.71875%200h1.8125m-5.4375%204.984375h8.15625A1.359375%201.359375%200%200%200%2012.6875%2010.875V3.625a1.359375%201.359375%200%200%200%20-1.359375%20-1.359375H3.171875A1.359375%201.359375%200%200%200%201.8125%203.625v7.25a1.359375%201.359375%200%200%200%201.359375%201.359375Z%22%20stroke-width%3D%221.5%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E"
{...props}
/>
);
const ProjectIcon = (props: any) => (
<Shape
_image="data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%3C!--%20Uploaded%20to%3A%20SVG%20Repo%2C%20www.svgrepo.com%2C%20Generator%3A%20SVG%20Repo%20Mixer%20Tools%20--%3E%3Csvg%20width%3D%22800px%22%20height%3D%22800px%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M10%2017L8%2015L10%2013M14%2013L16%2015L14%2017M13%203H8.2C7.0799%203%206.51984%203%206.09202%203.21799C5.71569%203.40973%205.40973%203.71569%205.21799%204.09202C5%204.51984%205%205.0799%205%206.2V17.8C5%2018.9201%205%2019.4802%205.21799%2019.908C5.40973%2020.2843%205.71569%2020.5903%206.09202%2020.782C6.51984%2021%207.0799%2021%208.2%2021H15.8C16.9201%2021%2017.4802%2021%2017.908%2020.782C18.2843%2020.5903%2018.5903%2020.2843%2018.782%2019.908C19%2019.4802%2019%2018.9201%2019%2017.8V9M13%203L19%209M13%203V8C13%208.55228%2013.4477%209%2014%209H19%22%20stroke%3D%22%23000000%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E"
{...props}
/>
);
const sequenceDiagram = {
title: "Runtime sequence diagram",
participants: {
cli: {
icon: CliIcon,
},
project: {
icon: ProjectIcon,
},
engine: {
icon: DockerIcon,
},
drawio: {
icon: DockerIcon,
},
tf: {
icon: DockerIcon,
},
},
messages: [
{
from: "cli",
to: "project",
message: "read config",
},
{
from: "project",
to: "cli",
message: "engine version",
return: true,
},
{
from: "cli",
to: "engine",
message: "run versioned engine",
},
{
from: "engine",
to: "project",
message: "read .tsx/data",
},
{
from: "project",
to: "engine",
message: "components/model",
return: true,
},
{
from: "engine",
to: "engine",
message: "engine commands",
dashed: true,
},
{
from: "engine",
to: "cli",
message: "output",
return: true,
},
],
interactions: [
{
title: "Render",
messages: [
{
from: "engine",
to: "engine",
message: "render drawio/tf",
},
],
},
{
title: "Diagram operations",
messages: [
{
from: "engine",
to: "drawio",
message: "render png",
},
{
from: "drawio",
to: "engine",
message: "png",
return: true,
},
],
},
{
title: "Tf operations",
messages: [
{
from: "engine",
to: "tf",
message: "terraform commands",
},
{
from: "tf",
to: "engine",
message: "up to date infrastructure",
return: true,
},
],
},
],
};
export default function App() {
return <SequenceDiagram {...sequenceDiagram} />;
}