The Automation Backbone: Our Build Pipeline
The Espalier documentation site is the result of a highly automated Docs-as-Code pipeline that ensures implementation and explanation remain perfectly synchronized. By treating documentation as a first-class build artifact, we move from a world of "eventual consistency" to a "Single Source of Truth" architecture.
Our pipeline utilizes Vento.js as our core rendering engine, following a three-stage transformation: Extraction, Generation, and Activation.
Stage 1: Extraction (Custom Elements Manifest)
The pipeline begins with the @custom-elements-manifest/analyzer. This tool performs static analysis on our Lit Element source files, scanning for JSDoc comments and property decorators.
- Input: JavaScript/TypeScript component files.
- Process: The analyzer builds an Abstract Syntax Tree (AST) to identify class members, events, and CSS parts.
- Output: A
custom-elements.jsonfile—a machine-readable map of our entire design system.
Stage 2: Generation (Eleventy + Vento.js)
We utilize Eleventy (11ty) paired with Vento.js as our rendering engine. Vento.js was selected for its ergonomic, JavaScript-first syntax, allowing us to write real JS logic anywhere in our templates.
- Template Binding: For every component, 11ty identifies the corresponding Markdown documentation file.
- Manifest Injection: We use a custom shortcode to pull data from the manifest. To display these tags in documentation without triggering build errors from 11ty's default pre-processors, we wrap them in a
rawblock:{% renderDocs className %} - Vento Compilation: Vento compiles the templates into high-performance static HTML. Because Vento is async-friendly, it handles our metadata processing without blocking the build.
Stage 3: Activation (Live JS Engine)
The final stage occurs in the client's browser. While the site is static, a custom JavaScript engine "activates" our documentation examples.
- Snippet Scanning: The engine scans for code blocks marked as
javascript. - Execution: It transforms these strings into executable code, injecting the resulting Lit components into a preview container.
- Isolation: This ensures that we are testing the component in a real-world DOM context, verifying that it responds to events and reactive property changes.
Challenge the Assumption: "Static Docs are Static"
A common assumption in web development is that static sites are only for reading. We challenge this. By combining a static build (11ty + Vento.js) with a dynamic injection engine, we create a Living Documentation system. This provides the performance and security of a static site with the interactivity of a heavyweight development environment like Storybook.
Strategic Impact: The CI/CD Quality Gate
Integrating this pipeline into our CI/CD workflow delivers strategic value:
- Automated Validation: If a developer renames a property in code but fails to update the JSDoc, the build can be configured to fail, preventing technical debt from reaching production.
- Developer Ergonomics: Vento.js provides a familiar environment for engineers, reducing the learning curve for maintaining the documentation site.
- Scalability: As Taproot IO grows, adding a new component requires zero manual documentation setup—the pipeline handles the "trellis" automatically.