Where to Find Export Handlers in the Design.md CLI: Complete File Guide
All export handlers in the Design.md repository are located under packages/cli/src/linter/, with the main orchestration logic residing in packages/cli/src/commands/export.ts.
The Design.md CLI (google-labs-code/design.md) converts parsed design tokens into various output formats through specialized handler classes. These handlers transform the internal DesignSystemState object into Tailwind configurations, DTCG JSON, or CSS custom properties. Understanding their exact file locations is essential for customizing output formats or debugging the export pipeline.
Export Handler Location Overview
The export functionality is modularized within the CLI package. Rather than residing in the commands directory, the implementation logic is co-located under the linter directory, separating the parsing logic from the command-line interface.
Each format is implemented as a dedicated handler class that follows a consistent pattern: accepting a DesignSystemState and returning a standardized result object containing the serialized data.
| Export Format | Handler Class | Source File Path |
|---|---|---|
Tailwind v3 (json-tailwind, tailwind) |
TailwindEmitterHandler |
packages/cli/src/linter/tailwind/handler.ts |
Tailwind v4 (css-tailwind) |
TailwindV4EmitterHandler |
packages/cli/src/linter/tailwind/v4/handler.ts |
Design Tokens (dtcg) |
DtcgEmitterHandler |
packages/cli/src/linter/dtcg/handler.ts |
CSS Custom Properties (css-vars) |
CssVarsEmitterHandler |
packages/cli/src/linter/css-vars/handler.ts |
Individual Export Handler Implementations
Tailwind v3 Handler
The TailwindEmitterHandler class in packages/cli/src/linter/tailwind/handler.ts handles exports for Tailwind v3. It maps colors, font families, font sizes, border radius, and spacing values into a JSON structure compatible with Tailwind's theme.extend configuration.
The handler constructs the output by calling mapping methods for each token category and returns a result object with the following structure:
return {
success: true,
data: {
theme: {
extend: {
colors: this.mapColors(state),
// ... other mapped properties
}
}
}
}
Tailwind v4 Handler
Located at packages/cli/src/linter/tailwind/v4/handler.ts, the TailwindV4EmitterHandler generates CSS @theme blocks for Tailwind v4 compatibility. While it uses the same mapping logic as the v3 handler, it outputs CSS syntax via the serializeTailwindV4 method instead of JSON.
DTCG Handler
The DtcgEmitterHandler in packages/cli/src/linter/dtcg/handler.ts produces Design Tokens Community Group (DTCG) compatible JSON files. It constructs a token file with the standard $schema property and organizes tokens into groups for colors, spacing, rounded corners, and typography.
Key implementation details from the source:
const file: DtcgTokenFile = {
$schema: DTCG_SCHEMA_URL,
// ... token groups
};
return { success: true, data: file };
CSS Variables Handler
The CssVarsEmitterHandler in packages/cli/src/linter/css-vars/handler.ts translates design tokens into CSS custom properties. It prefixes token names and outputs standard CSS variable declarations that can be imported directly into stylesheets.
How the Export Command Orchestrates Handlers
The export command in packages/cli/src/commands/export.ts acts as the dispatcher. It instantiates the appropriate handler based on the --format CLI argument and invokes the execute() method, passing the report.designSystem object extracted from the linting phase.
// packages/cli/src/commands/export.ts (excerpt)
if (format === 'css-tailwind') {
const handler = new TailwindV4EmitterHandler();
const result = handler.execute(report.designSystem);
// Write result.data to output...
} else if (format === 'json-tailwind' || format === 'tailwind') {
const handler = new TailwindEmitterHandler();
const result = handler.execute(report.designSystem);
} else if (format === 'dtcg') {
const handler = new DtcgEmitterHandler();
const result = handler.execute(report.designSystem);
} else if (format === 'css-vars') {
const handler = new CssVarsEmitterHandler();
const result = handler.execute(report.designSystem);
}
Each handler's execute() method returns a result object with a success boolean and a data property containing the serialized output, or an error property if serialization fails.
Working with Export Handlers: Code Examples
You can import and use these handlers programmatically outside of the CLI command structure. The following example demonstrates exporting to Tailwind v3 JSON:
import { TailwindEmitterHandler } from './linter/tailwind/handler.js';
import { lint } from './linter/lint.js';
import { readInput } from './utils.js';
async function exportTailwindJson(filePath: string) {
const content = await readInput(filePath);
const report = lint(content);
const handler = new TailwindEmitterHandler();
const result = handler.execute(report.designSystem);
if (result.success) {
console.log(JSON.stringify(result.data, null, 2));
} else {
console.error('Export failed:', result.error);
}
}
To export to the DTCG format instead:
import { DtcgEmitterHandler } from './linter/dtcg/handler.js';
async function exportDtcg(filePath: string) {
const content = await readInput(filePath);
const report = lint(content);
const handler = new DtcgEmitterHandler();
const result = handler.execute(report.designSystem);
console.log(JSON.stringify(result.data, null, 2));
}
Summary
- All export handlers are located under
packages/cli/src/linter/in the Design.md repository. - Four primary handlers exist:
TailwindEmitterHandler(v3),TailwindV4EmitterHandler(v4),DtcgEmitterHandler, andCssVarsEmitterHandler. - Entry point for export operations is
packages/cli/src/commands/export.ts, which dispatches to the appropriate handler based on the format flag. - Handler interface is consistent: instantiate the class, call
execute(designSystemState), and receive a result object withsuccessanddataproperties. - Pure function design allows handlers to be used independently of the CLI for custom build pipelines or testing.
Frequently Asked Questions
Where are the export handlers located in the Design.md codebase?
All export handlers are located under the packages/cli/src/linter/ directory. Specific implementations reside in subdirectories such as tailwind/, tailwind/v4/, dtcg/, and css-vars/. The command-line entry point that orchestrates these handlers is found at packages/cli/src/commands/export.ts.
How does the export command decide which handler to use?
The export command checks the --format argument provided by the user. Based on the value (e.g., css-tailwind, json-tailwind, dtcg, or css-vars), it instantiates the corresponding handler class (such as TailwindV4EmitterHandler or DtcgEmitterHandler) and calls its execute() method with the parsed design system state.
Can I use the export handlers outside of the CLI command?
Yes, the export handlers are designed as independent classes that can be imported directly into your own scripts. They expose an execute() method that accepts a DesignSystemState object and returns a serializable result, making them suitable for custom build pipelines, testing, or integration into other tools without invoking the CLI.
Which file contains the CssVarsEmitterHandler implementation?
The CssVarsEmitterHandler class is defined in packages/cli/src/linter/css-vars/handler.ts. This handler converts design tokens into CSS custom properties (CSS variables) and follows the same execution pattern as the other export handlers in the codebase.
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 →