How Archify Generates and Compiles JSON Schemas: A Deep Dive into Runtime Validation
Archify compiles static JSON schema files into fast AJV validator functions at build time, letting the CLI validate diagram definitions without loading raw schemas at runtime.
Archify's JSON schema system ensures every diagram—whether architecture, workflow, sequence, dataflow, or lifecycle—is structurally valid before rendering begins. This article explains how the tt-a1i/archify repository generates and compiles these schemas, tracing the complete path from static definition files to runtime validation.
Static Schema Definitions in archify/schemas/
Every supported diagram type ships with a hand-crafted JSON Schema file stored in archify/schemas/. These files define the exact structure, types, and constraints each diagram must follow.
The schema files include:
architecture.schema.jsonworkflow.schema.jsonsequence.schema.jsondataflow.schema.jsonlifecycle.schema.json
These schemas are version-controlled alongside the source code and serve as the single source of truth for diagram validity. When requirements change, the Archify team updates these static files directly.
Compiling Schemas to AJV Validators
The compilation happens in archify/renderers/shared/generated-validators.mjs. This build-time script transforms each .schema.json file into a compiled AJV validator function using AJV v8+.
The compilation workflow follows this pattern:
import Ajv from "ajv";
import addFormats from "ajv-formats";
import { readFileSync } from "fs";
import { join } from "path";
const ajv = new Ajv({ allErrors: true, strict: false });
addFormats(ajv);
function compileSchema(name) {
const schemaPath = join(import.meta.url, `../schemas/${name}.schema.json`);
const schema = JSON.parse(readFileSync(new URL(schemaPath), "utf8"));
return ajv.compile(schema);
}
export const architecture = compileSchema("architecture");
export const workflow = compileSchema("workflow");
export const sequence = compileSchema("sequence");
export const dataflow = compileSchema("dataflow");
export const lifecycle = compileSchema("lifecycle");
Key configuration choices in this compilation step:
allErrors: true— Collects all validation errors, not just the firststrict: false— Allows some JSON Schema draft flexibilityajv-formats— Enables format validators for fields likeurianddate-time
The compiled validators export as named exports, creating a plain object where each key matches a diagram type. This bundling eliminates filesystem reads at runtime.
Runtime Validation Flow
When the CLI processes a diagram, validation occurs before any rendering code executes. The entry point in archify/bin/archify.mjs orchestrates this through inputDiagnostic and rendererFailure handlers.
The validation sequence works as follows:
- CLI receives a render command with a diagram file
- Appropriate validator imported from
generated-validators.mjs - Validator runs against the parsed JSON definition
- On success: proceed to renderer (e.g.,
render-architecture.mjs) - On failure: emit detailed error pointing to specific schema violations
Programmatic Validation Example
You can use the compiled validators directly in your own scripts:
import { architecture } from "./renderers/shared/generated-validators.mjs";
import { readFileSync } from "fs";
const definition = JSON.parse(readFileSync("examples/web-app.architecture.json", "utf8"));
if (!architecture(definition)) {
console.error("Invalid architecture JSON:", architecture.errors);
} else {
console.log("Definition is valid – ready for rendering");
}
The architecture.errors property contains full AJV error objects with paths, messages, and schema locations.
CLI Validation Example
The default archify render command runs compiled validation automatically:
archify render architecture examples/web-app.architecture.json output.html
If validation fails, Archify aborts with structured diagnostics:
[delta/base-validation] Base snapshot failed validation. Fix: repair the JSON syntax and run validation again.
Performance and Design Rationale
This two-stage approach—static schema → compiled validator—delivers significant advantages:
- Speed: Compiled validators skip schema parsing and reference resolution at runtime
- **Portability
:generated-validators.mjsbundles all needed code, noschemas/` directory required in production - Clarity: Validation errors map directly back to source schema rules
- **Maintainability`: Schema changes require only rebuilding the validator module
According to the tt-a1i/archify source code, renderers like archify/renderers/architecture/render-architecture.mjs import validators directly from the generated module, ensuring zero runtime schema loading overhead.
Summary
- Static JSON Schema files in
archify/schemas/define diagram requirements generated-validators.mjscompiles these to AJV validators at build time using AJV v8+ withallErrors: true- Compiled exports (
architecture,workflow,sequence,dataflow,lifecycle) provide synchronous validation archify/bin/archify.mjsruns validation before delegating to specialized renderers- Rich error diagnostics point users to exact schema violations
Frequently Asked Questions
What JSON Schema draft does Archify use?
The generated-validators.mjs compiler uses AJV's default draft support (typically JSON Schema draft-07 or 2019-09 depending on AJV v8 configuration). The strict: false option provides flexibility across schema versions, though individual schema files in archify/schemas/ follow consistent patterns.
Can I validate diagrams without installing the full CLI?
Yes. Import the specific validator from archify/renderers/shared/generated-validators.mjs and call it programmatically. This works in any Node.js environment with AJV installed—no CLI overhead required.
How do I add a new diagram type to Archify?
Create a new .schema.json file in archify/schemas/, then add the corresponding compileSchema() call and export in generated-validators.mjs. Rebuild the package to regenerate the compiled validators with your new schema included.
What happens if my JSON has multiple validation errors?
Because allErrors: true is set in the AJV configuration, the validator collects every violation rather than stopping at the first. Access validator.errors after a failed call to see the complete array of error objects with paths and messages.
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 →