Create your first Converter
This guide walks you through creating a custom Swerr converter from scratch. By the end, you will understand how converters work, how data flows through them, and how to implement your own output format.
What Is a Converter?
A converter is responsible for transforming the generated Swerr scheme into a specific output format, such as HTML, Markdown, JSON, or any custom representation.
From a technical perspective, a converter is:
-
a function
-
that receives a configuration object
-
and the generated
SwerrScheme -
and returns a
Promise<void>
Converter Architecture
Swerr Configuration
Converters are registered in the converter array of the SwerrConfig:
export interface SwerrConfig {
sourceFile: {
inputDir?: string;
meta?: {
projectName?: string;
version?: string;
description?: string;
};
export?: {
saveToFile?: boolean;
fileName?: string;
outputDir?: string;
};
options?: {
ignoreDirs?: string[];
whitelistExtensions?: string[];
}
},
converter: ConverterConfig<any>[]
}
Each converter entry consists of a factory function and its configuration object.
Converter Config
export interface ConverterConfig<CFG> {
factory: ConverterFn<CFG>;
config: CFG;
}
-
factory– the converter function -
config– the converter-specific configuration passed to the factory
Converter Function Signature
Every converter must follow this function signature:
export type ConverterFn<CFG> = (
config: CFG,
scheme: SwerrScheme
) => Promise<void>;
Understanding Swerr Scheme
The SwerrScheme is the normalized data structure generated by the Swerr CLI. It contains all extracted information from your exception classes and JSDoc annotations.
export interface SwerrScheme {
name: string;
description: string;
version: string;
errors: SwerrSchemeError[];
}
Errors
export interface SwerrSchemeError {
name: string;
description: string;
tags: SwerrSchemeTag[];
}
Each error represents a detected exception class.
Tags
export interface SwerrSchemeTag {
name: string;
description: string;
}
Tags are derived from JSDoc annotations and allow converters to enrich the output with additional metadata.
Step-by-Step: Building a Converter
Below is a simplified example of an HTML converter implementation:
Import Dependencies
import { LogUtils, SwerrScheme } from "@swerr/core";
import { YourConfigInterface } from "./interface.js";
Implement the Converter
Logging Note
For consistency across the Swerr ecosystem, converters should use the providedLogUtilsfor all log output.
Avoid usingconsole.logdirectly, asLogUtilsensures unified formatting, log levels, and user experience.
export const converter = async (config: YourConfigInterface, scheme: SwerrScheme) => {
if (!config.outputPath) {
LogUtils.error("No output path specified in the converter configuration.")
return;
}
// Your Logic here
}
Key Responsibilities of a Converter
A well-behaved converter should:
-
validate its configuration
-
read data exclusively from the provided
SwerrScheme -
generate output deterministically
-
handle file system operations safely
-
provide meaningful log output
Registering Your Converter
Once implemented, register your converter in swerr.config.js:
converter: [
{
factory: converter,
config: {
outputPath: "docs",
}
}
]
Best Practices
-
Keep converters stateless
-
Avoid mutating the
SwerrScheme -
Prefer single-file output when possible
-
Fail gracefully and log actionable errors
Summary
Converters are the final step in the Swerr pipeline. They receive a fully normalized data model and are free to transform it into any format required.
By following the structure and examples above, you can quickly build and integrate your own custom converters into the Swerr ecosystem.