How archify Renderers Convert JSON to HTML and SVG
archify renderers convert JSON diagram descriptions into standalone HTML files with embedded SVG by loading and validating the input, computing diagram-specific layouts, and injecting the resulting SVG into a static HTML template.
The archify project provides typed renderers for architecture, workflow, sequence, dataflow, and lifecycle diagrams. Each renderer follows a consistent three-stage pipeline implemented in archify/renderers/shared/cli.mjs and specialized per diagram type in dedicated renderer modules.
The Three-Stage Conversion Pipeline
Stage 1: Load and Validate with loadDiagram()
Every renderer begins by invoking loadDiagram() from archify/renderers/shared/cli.mjs. This utility function:
- Resolves the input JSON file path from command-line arguments
- Parses and validates the JSON against the diagram-type-specific schema
- Validates guided views and relationship identifiers for cross-collection consistency
- Retrieves the HTML template from
archify/assets/template.html - Constructs the output path object
The validation ensures that architectural components, sequence participants, workflow nodes, or lifecycle states conform to expected structures before rendering begins.
Stage 2: Compute Layout and Generate SVG
Each typed renderer imports shared utilities from archify/renderers/shared/ and implements diagram-specific layout logic:
| Renderer | Source File | Layout Focus |
|---|---|---|
| Architecture | archify/renderers/architecture/render-architecture.mjs |
Grid-based component positioning, boundary containment, connection routing |
| Sequence | archify/renderers/sequence/render-sequence.mjs |
Fixed-column participant layout, lifeline coordinates, message arc positioning |
| Workflow | archify/renderers/workflow/render-workflow.mjs |
DAG node placement, edge routing through waypoints |
| Dataflow | archify/renderers/dataflow/render-dataflow.mjs |
Port-based node positioning, flow path computation |
| Lifecycle | archify/renderers/lifecycle/render-lifecycle.mjs |
State arrangement, transition curve routing |
The renderSvg() function in each module assembles the SVG markup with:
- Accessibility attributes via
svgRootAttrsandsvgAccessibleText - SVG
<defs>fromrenderDefinitions() - Background grid, boundaries, connections, components, and labels
- A complete legend block
Layout validation helpers like cleanFlowProblems() and cleanCrossingProblems() ensure visual correctness before SVG generation.
Stage 3: Template Injection with writeDiagram()
The final stage occurs in writeDiagram(), also from cli.mjs:
writeDiagram({
outPath,
template,
diagramType: 'architecture',
meta: arch.meta,
footerLabel: 'Architecture diagram',
svg, // Generated SVG string
cards, // Optional evidence cards
});
This function calls applyTemplate() to substitute placeholders in archify/assets/template.html with:
- Page
<title>and<meta>tags frommeta.titleandmeta.subtitle - The complete SVG markup
- Footer UI controls and guided-view navigation
- Visual preset data attributes
The result is a self-contained HTML file that requires no external dependencies.
Command-Line Usage
Invoke any renderer directly with Node.js:
# Architecture diagram
node archify/renderers/architecture/render-architecture.mjs \
examples/web-app.architecture.json \
output/web-app.html
# Sequence diagram
node archify/renderers/sequence/render-sequence.mjs \
examples/cache-miss-request.sequence.json \
output/cache-miss.html
# Workflow diagram
node archify/renderers/workflow/render-workflow.mjs \
examples/release-delivery.workflow.json \
output/release.html
# Dataflow diagram
node archify/renderers/dataflow/render-dataflow.mjs \
examples/api-gateway.dataflow.json \
output/gateway.html
# Lifecycle diagram
node archify/renderers/lifecycle/render-lifecycle.mjs \
examples/deployment.lifecycle.json \
output/deploy.html
Programmatic Integration
Embed rendering in Node.js scripts using child_process:
import { spawnSync } from 'node:child_process';
function renderDiagram(type, inputJson, outputHtml) {
const result = spawnSync('node', [
`archify/renderers/${type}/render-${type}.mjs`,
inputJson,
outputHtml
], { encoding: 'utf-8' });
if (result.error) throw result.error;
console.log(`Rendered: ${outputHtml}`);
}
// Example usage
renderDiagram(
'architecture',
'diagrams/system.architecture.json',
'dist/system.html'
);
Renderer Internals: Architecture Example
The render-architecture.mjs module demonstrates the full pattern:
// From archify/renderers/architecture/render-architecture.mjs
// 1. Load and validate
const { diagram: arch, template, outPath } = loadDiagram({
rendererDir: new URL('.', import.meta.url).pathname,
diagramType: 'architecture',
defaultExample: 'web-app.architecture.json',
argv: process.argv.slice(2)
});
// 2. Compute layout
const grid = gridLayout(arch.components, arch.layout || {});
const viewBox = computeViewBox(grid.extents);
// 3. Generate SVG with components, boundaries, connections
const svg = renderSvg({
viewBox,
definitions: renderDefinitions(),
background: renderGrid(grid),
content: [
...renderBoundaries(arch.boundaries),
...renderConnections(arch.connections),
...renderComponents(arch.components),
renderLegend(arch.legend)
].join('\n')
});
// 4. Write final HTML
writeDiagram({
outPath,
template,
diagramType: 'architecture',
meta: arch.meta,
footerLabel: `${arch.meta?.title || 'Architecture'} diagram`,
svg,
cards: arch.cards
});
The sequence renderer follows an analogous structure but replaces grid layout with column-based participant positioning and adds lifeline rendering for message flows.
Key Source Files
archify/renderers/shared/cli.mjs— CLI infrastructure:loadDiagram(),writeDiagram(), validation orchestrationarchify/renderers/shared/utils.mjs— Shared helpers:esc(),renderDefinitions(), template utilitiesarchify/renderers/architecture/render-architecture.mjs— Architecture-specific layout and SVG generationarchify/renderers/sequence/render-sequence.mjs— Sequence diagram lifelines and message renderingarchify/renderers/workflow/render-workflow.mjs— Workflow DAG visualizationarchify/renderers/dataflow/render-dataflow.mjs— Dataflow port and flow renderingarchify/renderers/lifecycle/render-lifecycle.mjs— State machine visualizationarchify/assets/template.html— HTML scaffold with substitution placeholders
Summary
- archify renderers convert JSON to HTML/SVG through a validated, three-stage pipeline
loadDiagram()handles parsing, schema validation, and guided-view verification inarchify/renderers/shared/cli.mjs- Typed renderer modules (
render-architecture.mjs,render-sequence.mjs, etc.) implement diagram-specific layouts and SVG generation viarenderSvg() writeDiagram()injects the SVG and metadata intoarchify/assets/template.htmlto produce standalone output files- The architecture supports five diagram types with consistent patterns but specialized geometry for each visual domain
Frequently Asked Questions
What JSON schema do archify renderers validate against?
Each renderer validates input against a diagram-type-specific JSON Schema defined in the renderer's directory. The loadDiagram() function in cli.mjs selects the appropriate schema based on the diagram_type field and enforces structural requirements before layout computation begins.
Can I customize the HTML template used for output?
Yes. The template.html file in archify/assets/ contains substitution placeholders that applyTemplate() replaces at runtime. Modify this file to change the page structure, CSS styling, or JavaScript behavior. Pass a custom template path via renderer configuration if supported by the specific implementation.
How do archify renderers handle large diagrams?
Renderers compute view boxes automatically from layout extents and include zoom/pan controls in the generated HTML. The SVG output is static and self-contained, so browser-native zooming works without server dependencies. For very large diagrams, consider enabling guided views to present focused subsets sequentially.
Are the generated SVGs accessible?
Yes. Every renderer injects accessibility features via svgAccessibleText() and svgRootAttrs, including <title> elements, aria-label attributes, and semantic data-* attributes for screen reader compatibility. The legend block provides textual alternatives to visual encoding.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →