High-Level Architecture
Relevant source files
The following files were used as context for generating this wiki page:
The chemd project is a specialized system designed to transform chemical experiment documentation—written in a Markdown-based domain language—into structured data and visual representations. Its primary goal is to maintain the simplicity of plain text files while enabling chemical objects (molecules, reactions) to exist as structured Abstract Syntax Tree (AST) nodes.
The architecture is built on a multi-stage pipeline that separates syntax parsing, semantic resolution, and visual styling. This ensures that the core chemical data (semantic layer) remains independent of how it is visually rendered (style layer), allowing the same source document to drive HTML previews, machine-readable JSON, SVG structure diagrams, and DOCX exports.
Sources: chemd-v0.1-architecture.md:5-24, chemd-v0.1-spec.md:12-23
Multi-Stage Processing Pipeline
The system operates as a linear pipeline. This separation of concerns allows for independent validation and diagnostics at every stage of the document lifecycle.
The pipeline architecture ensures that style resolution is independent of semantic object parsing, and diagnostics can be attached at any point in the flow.
Sources: chemd-v0.1-architecture.md:65-82
System Modules and Monorepo Structure
The project is organized as a pnpm workspace and Turborepo monorepo, divided into domain-specific packages and application entry points.
Core Packages
| Package | Responsibility |
|---|---|
packages/core | Shared domain types, AST definitions, and validation helpers. |
packages/parser | Reads frontmatter and parses Markdown into a normalized semantic AST. |
packages/resolver | Handles object indexing, template expansion, and reference resolution. |
packages/render-profile | Manages visual styles (bond lengths, fonts) and merges overrides. |
packages/renderer-* | Specific output modules for HTML, JSON, SVG, and DOCX formats. |
Sources: AGENTS.md:10-18, chemd-v0.1-architecture.md:95-144
Application Layers
Logic is implemented in packages/* first before being integrated into high-level applications like apps/web, which serves as the primary UI entry point using Next.js 15.
Sources: AGENTS.md:10-14
Semantic AST vs. Render Options
A fundamental architectural boundary exists between the Semantic AST and Render Options. Semantic blocks (like a molecule or reaction) are forbidden from owning style properties directly.
Architecture Principles
- Semantic AST: Contains frontmatter, molecule/reaction data, references, and normalized document structure.
- Render Options: Contains resolved tokens such as
bond_length,bond_line_width, font sizing, and color modes.
Render options must be mutable without changing the underlying semantic meaning of the chemical data.
Sources: chemd-v0.1-architecture.md:46-61, chemd-v0.1-architecture.md:275-298
Parsing and Resolution Logic
The parsing strategy uses a hybrid approach:
- Frontmatter Ingestion: Uses a custom YAML-based parser to extract metadata and render profiles.
- Block Detection: Intercepts fenced directive-style syntax (e.g.,
:::molecule) and inline chemistry (:chem[...]). - Reference Resolution: Resolves lightweight tokens like
@id.fieldor@meta.keyagainst the built-in object index.
Template Engine
The template system is intentionally limited to prevent arbitrary code execution. It supports alias binding and parameter injection, expanding templates into AST fragments before the renderers execute.
Sources: chemd-v0.1-architecture.md:148-175, chemd-v0.1-architecture.md:255-271, packages/parser/src/frontmatter/parse-frontmatter.ts:474-515
Rendering Architecture
Renderers are consumers of the resolved AST and the final RenderOptions object.
| Renderer | Input | Output |
|---|---|---|
| HTML | Resolved AST + Options | Interactive preview with inline SVG assets. |
| JSON | Resolved AST + Options | Serialized object graph and diagnostics. |
| SVG | Molecule/Reaction nodes | Visual assets via an RDKit.js adapter. |
| DOCX | Export-oriented HTML/MD | Payload for a Pandoc-based bridge. |
Sources: chemd-v0.1-architecture.md:302-325, packages/renderer-html/src/index.ts:1145-1168
Diagnostics System
The system tracks issues throughout the pipeline using a standardized diagnostic shape.
interface Diagnostic {
code: string;
severity: 'info' | 'warning' | 'error';
message: string;
position?: SourceRange;
nodeId?: string;
}
Common diagnostic codes include E_DUPLICATE_ID, E_TEMPLATE_CYCLE, and W_UNRESOLVED_REFERENCE. The architecture ensures that errors are localized; a broken block or profile selection should not crash the processing of unrelated document sections.
Sources: chemd-v0.1-architecture.md:347-367, packages/compiler/tests/compiler.test.ts:109-120
Summary
The chemd architecture is defined by its rigorous separation of semantic chemistry data from visual presentation. By utilizing a multi-stage pipeline and a structured AST, it provides a robust framework for chemical documentation that is both human-readable and machine-actionable. The monorepo structure facilitates modular development, ensuring that parsing, resolution, and rendering remain decoupled and independently testable.