Quick Start
Get up and running with Trazo in minutes.
Trazo is a deterministic code-to-diagram layout engine — flowcharts and git graphs. Pure-TypeScript core with an optional React SVG renderer.
Install
pnpm add @joycostudio/trazoFlowchart
import { layoutFlow } from "@joycostudio/trazo";
import { Graph } from "@joycostudio/trazo/react";
const graph = layoutFlow({
kind: "flow",
nodes: [
{ id: "a", label: "Request", shape: "stadium", role: "primary" },
{ id: "b", label: "Process" },
{ id: "c", label: "Done", shape: "stadium", role: "success" },
],
edges: [
{ from: "a", to: "b" },
{ from: "b", to: "c" },
],
});
// React (or any React Server Component):
<Graph graph={graph} title="My flowchart" />Git graph
import { layoutGit } from "@joycostudio/trazo";
const graph = layoutGit({
commits: [
{ id: "c1", parents: [], message: "Initial commit" },
{ id: "c2", parents: ["c1"], message: "Add feature", branch: "feat/x" },
{ id: "c3", parents: ["c1"], message: "Hotfix", branch: "main" },
{ id: "c4", parents: ["c3", "c2"], message: "Merge feat/x" },
],
});
<Graph graph={graph} title="Commit history" />From playground to code
The playground uses the same layout engine you call from TypeScript. Copy a diagram from the editor and translate it line-by-line to the API.
Flow DSL → layoutFlow
Each node line becomes a FlowNode, each arrow becomes a FlowEdge:
flow TD
A(["Request"]):primary ==> B["Process"]
B --> C["Done"]:successlayoutFlow({
kind: "flow",
nodes: [
{ id: "A", label: "Request", shape: "stadium", role: "primary" },
{ id: "B", label: "Process" },
{ id: "C", label: "Done", role: "success" },
],
edges: [
{ from: "A", to: "B" },
{ from: "B", to: "C" },
],
})DSL shapes map to shape: [box] → "box", (["stadium"]) → "stadium", {diamond} → "diamond", [("cylinder")] → "cylinder". :role suffixes map to role. ==> (thick arrow) maps to colored: true on the edge.
Git DSL → layoutGit
The DSL is imperative (branch/checkout/merge statements that build the graph as you go). The API is declarative — you provide the final commit graph directly, with explicit parents arrays:
commit a1 (Alice) : Initial commit
branch feat/x
commit b1 (Bob) : Add feature
checkout main
merge feat/x : MergelayoutGit({
commits: [
{ id: "a1", parents: [], hash: "a1", author: "Alice", message: "Initial commit", branch: "main" },
{ id: "b1", parents: ["a1"], author: "Bob", message: "Add feature", branch: "feat/x" },
{ id: "m1", parents: ["a1", "b1"], message: "Merge", branch: "main" },
],
})parents[0] is always the mainline parent. A merge commit has two or more parents — mainline first, merged-in branch second.
Key properties
- Pure TypeScript. No DOM, no canvas, no
window. The layout runs in Node just as well as in the browser — identical output on server and client. - Deterministic. Equal input always produces the same
PositionedGraph. Safe for SSR: the server-rendered SVG and the first client render are byte-identical, so there are no hydration mismatches. <Graph>is a pure function of props. No hooks, no effects, no browser globals — use it in a React Server Component and ship zero client JS for the diagram.
Playground
Try it interactively at / — the playground renders the SVG on the server and hydrates for live editing.