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 svgRootAttrs and svgAccessibleText
  • SVG <defs> from renderDefinitions()
  • 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 from meta.title and meta.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 orchestration
  • archify/renderers/shared/utils.mjs — Shared helpers: esc(), renderDefinitions(), template utilities
  • archify/renderers/architecture/render-architecture.mjs — Architecture-specific layout and SVG generation
  • archify/renderers/sequence/render-sequence.mjs — Sequence diagram lifelines and message rendering
  • archify/renderers/workflow/render-workflow.mjs — Workflow DAG visualization
  • archify/renderers/dataflow/render-dataflow.mjs — Dataflow port and flow rendering
  • archify/renderers/lifecycle/render-lifecycle.mjs — State machine visualization
  • archify/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 in archify/renderers/shared/cli.mjs
  • Typed renderer modules (render-architecture.mjs, render-sequence.mjs, etc.) implement diagram-specific layouts and SVG generation via renderSvg()
  • writeDiagram() injects the SVG and metadata into archify/assets/template.html to 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →