widdershins
OpenAPI / Swagger, AsyncAPI & Semoasa definitions to (re)Slate compatible markdown
Top Related Projects
Beautiful static documentation for your API
📘 OpenAPI/Swagger-generated API Reference Documentation
Build beautiful, interactive API Docs with embeddable React or Web Components, powered by OpenAPI and Markdown.
Swagger UI is a collection of HTML, JavaScript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API.
Easy OpenAPI specs and Swagger UI for your Flask API
Quick Overview
Widdershins is an OpenAPI / Swagger / AsyncAPI / Semoasa definition to documentation converter. It takes API definitions in various formats and generates human-readable documentation in Markdown, HTML, or Slate/Shins-compatible Markdown. This tool is particularly useful for developers and technical writers working with API documentation.
Pros
- Supports multiple input formats (OpenAPI 3.0/2.0, AsyncAPI 2.0, Semoasa)
- Generates documentation in various output formats (Markdown, HTML, Slate)
- Highly customizable with templates and configuration options
- Active development and community support
Cons
- Learning curve for advanced customization
- May require additional tools for full HTML rendering (e.g., Shins)
- Limited support for older API definition formats
- Some users report occasional inconsistencies in output formatting
Code Examples
- Basic usage with OpenAPI 3.0:
const widdershins = require('widdershins');
const fs = require('fs');
let options = {};
let apiDefinition = JSON.parse(fs.readFileSync('openapi.json', 'utf8'));
widdershins.convert(apiDefinition, options)
.then(output => {
fs.writeFileSync('output.md', output, 'utf8');
})
.catch(err => {
console.error(err);
});
- Customizing output with options:
let options = {
language_tabs: [{ javascript: 'JavaScript' }, { python: 'Python' }],
search: true,
theme: 'darkula',
customApiKeyValue: 'Bearer {api-key}'
};
widdershins.convert(apiDefinition, options)
.then(output => {
// Process output
});
- Using with AsyncAPI 2.0:
const yaml = require('js-yaml');
let asyncApiDefinition = yaml.load(fs.readFileSync('asyncapi.yaml', 'utf8'));
let options = { asyncapi: true };
widdershins.convert(asyncApiDefinition, options)
.then(output => {
// Process output
});
Getting Started
To use Widdershins in your project:
-
Install Widdershins:
npm install widdershins
-
Create a basic script (e.g.,
generate-docs.js
):const widdershins = require('widdershins'); const fs = require('fs'); let options = {}; let apiDefinition = JSON.parse(fs.readFileSync('api-definition.json', 'utf8')); widdershins.convert(apiDefinition, options) .then(output => { fs.writeFileSync('api-documentation.md', output, 'utf8'); console.log('Documentation generated successfully!'); }) .catch(err => { console.error('Error generating documentation:', err); });
-
Run the script:
node generate-docs.js
This will generate Markdown documentation from your API definition file.
Competitor Comparisons
Beautiful static documentation for your API
Pros of Slate
- Provides a beautiful, responsive, and customizable documentation template
- Supports multiple programming languages for code samples
- Offers a live preview feature for real-time editing
Cons of Slate
- Requires more setup and configuration compared to Widdershins
- Less flexible in terms of input formats (primarily focused on Markdown)
- May have a steeper learning curve for non-technical users
Code Comparison
Slate (Ruby):
require 'middleman'
require 'middleman-syntax'
require 'middleman-autoprefixer'
require 'middleman-sprockets'
require 'rouge'
require 'redcarpet'
Widdershins (JavaScript):
const widdershins = require('widdershins');
const fs = require('fs');
let options = {};
let apiSpec = fs.readFileSync('input.yaml', 'utf8');
widdershins.convert(apiSpec, options, (err, output) => {
// Process output
});
Slate focuses on providing a complete documentation solution with a polished UI, while Widdershins is more specialized in converting API specifications to various documentation formats. Slate requires Ruby and uses Middleman for static site generation, whereas Widdershins is a Node.js-based tool that can be easily integrated into existing workflows. Both tools have their strengths, and the choice between them depends on specific project requirements and team preferences.
📘 OpenAPI/Swagger-generated API Reference Documentation
Pros of Redoc
- Offers a sleek, modern, and responsive UI for API documentation
- Supports interactive features like "Try it out" functionality
- Provides better customization options for branding and theming
Cons of Redoc
- Limited to generating HTML documentation only
- Requires more setup and configuration for advanced features
- May have performance issues with very large API specifications
Code Comparison
Redoc (HTML):
<!DOCTYPE html>
<html>
<head>
<title>API Documentation</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
<style>body { margin: 0; padding: 0; }</style>
</head>
<body>
<redoc spec-url='http://petstore.swagger.io/v2/swagger.json'></redoc>
<script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"></script>
</body>
</html>
Widdershins (JavaScript):
const widdershins = require('widdershins');
const fs = require('fs');
let options = {};
options.codeSamples = true;
options.language_tabs = [{ 'shell': 'Shell' }, { 'http': 'HTTP' }, { 'javascript': 'JavaScript' }];
widdershins.convert(inputSpec, options)
.then(output => {
fs.writeFileSync('output.md', output, 'utf8');
});
Build beautiful, interactive API Docs with embeddable React or Web Components, powered by OpenAPI and Markdown.
Pros of Elements
- Offers a complete API documentation solution with interactive components
- Supports multiple API description formats (OpenAPI, AsyncAPI, JSON Schema)
- Provides a customizable and responsive UI out of the box
Cons of Elements
- Requires more setup and configuration compared to Widdershins
- May have a steeper learning curve for users new to React-based components
- Limited flexibility in output format customization
Code Comparison
Elements (React component):
import { API } from '@stoplight/elements';
function MyAPIDocumentation() {
return <API apiDescriptionUrl="https://api.example.com/openapi.yaml" />;
}
Widdershins (Node.js usage):
const widdershins = require('widdershins');
const options = {};
widdershins.convert(apiDefinition, options, (err, markdown) => {
console.log(markdown);
});
Elements focuses on providing a ready-to-use React component for rendering API documentation, while Widdershins is primarily a command-line tool for converting API definitions to various documentation formats. Elements offers a more interactive and visually appealing solution, but Widdershins provides greater flexibility in output formats and is easier to integrate into existing documentation workflows.
Swagger UI is a collection of HTML, JavaScript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API.
Pros of Swagger UI
- Provides an interactive, user-friendly interface for exploring and testing APIs
- Widely adopted and supported by the OpenAPI community
- Offers customization options for branding and theming
Cons of Swagger UI
- Limited to displaying API documentation in a specific format
- Requires additional setup for integration with existing documentation systems
- May not be suitable for generating static documentation files
Code Comparison
Swagger UI (JavaScript):
SwaggerUIBundle({
url: "https://petstore.swagger.io/v2/swagger.json",
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
layout: "StandaloneLayout"
})
Widdershins (JavaScript):
const widdershins = require('widdershins');
let options = {};
widdershins.convert(swaggerJson, options)
.then(output => {
console.log(output);
});
Key Differences
- Swagger UI focuses on rendering interactive API documentation in the browser
- Widdershins is designed for converting OpenAPI/Swagger definitions to various documentation formats
- Swagger UI is more suitable for live API exploration, while Widdershins is better for generating static documentation
Use Cases
- Choose Swagger UI for interactive API documentation and testing
- Opt for Widdershins when generating Markdown or other static documentation formats from OpenAPI specifications
Easy OpenAPI specs and Swagger UI for your Flask API
Pros of flasgger
- Integrates directly with Flask applications, making it easy to generate Swagger/OpenAPI documentation from Flask routes
- Provides a web-based Swagger UI for interactive API documentation and testing
- Supports automatic validation of request data against defined schemas
Cons of flasgger
- Limited to Flask applications, whereas Widdershins supports multiple API description formats
- May require more manual configuration for complex API structures
- Less flexible in terms of output formats compared to Widdershins
Code Comparison
flasgger:
from flask import Flask
from flasgger import Swagger
app = Flask(__name__)
swagger = Swagger(app)
@app.route('/api/<string:username>')
def get_user(username):
"""
This is an example endpoint
---
parameters:
- name: username
in: path
type: string
required: true
responses:
200:
description: A user object
"""
return {'username': username}
Widdershins:
const widdershins = require('widdershins');
const options = {
tocSummary: false,
language_tabs: [{ 'javascript--nodejs': 'Node.JS' }],
theme: 'darkula'
};
widdershins.convert(inputSpec, options)
.then(output => console.log(output))
.catch(err => console.error(err));
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
widdershins
OpenAPI / Swagger / AsyncAPI / Semoasa definition to Slate / ReSlate compatible markdown
Widdershins adverb:
- In a direction contrary to the sun's course;
- anticlockwise;
- helping you produce static documentation from your OpenAPI 3.0 / Swagger 2.0 / AsyncAPI 1.x / Semoasa 0.1.0 definition
News
- Version 4.0 changes:
- Now uses Promises not callbacks
- Option to output html directly, and to ReSpec format
- Unified JavaScript and Node.js code-samples, PHP added
restrictions
column (readOnly
/writeOnly
) added to schema templates- Numerous bug fixes
- As of v3.0.0 Widdershins no longer expands the definition of OpenAPI body parameters / requestBodies by default, unless they have an inline schema. You can restore the old behaviour by using the
--expandBody
option. - You may limit the depth of schema examples using the
--maxDepth
option. The default is 10. - To omit schemas entirely, please copy and customise the
main.dot
template. - As of v3.1.0 Widdershins includes a generated
Authorization
header in OpenAPI code samples. If you wish to omit this, see here.
To install
- Clone the git repository, and
npm i
to install dependencies, or npm install -g widdershins
to install globally
Getting started
Widdershins is generally used as a stage in an API documentation pipeline. The pipeline begins with an API definition in OpenAPI 3.x, OpenAPI 2.0 (fka Swagger), API Blueprint, AsyncAPI or Semoasa format. Widdershins converts this description into markdown suitable for use by a renderer, such as Slate, ReSlate, Shins (deprecated) or html suitable for use with ReSpec.
If you need to create your input API definition, this list of available editors may be useful.
More in-depth documentation is available here.
Examples
node widdershins --search false --language_tabs 'ruby:Ruby' 'python:Python' --summary defs/petstore3.json -o petstore3.md
Options
CLI parameter name | JavaScript parameter name | Type | Default value | Description |
---|---|---|---|---|
--clipboard | options.clipboard | boolean | true | Sets the value of the code_clipboard property in the heading, so that markdown processors can include clipboard support. |
--customApiKeyValue | options.customApiKeyValue | string | ApiKey | Set a custom API key value to use as the API key in generated code examples. |
--expandBody | options.expandBody | boolean | false | If a method's requestBody parameter refers to a schema by reference (not with a inline schema), by default, Widdershins shows only a reference to this parameter. Set this option to true to expand the schema and show all properties in the request body. |
--headings | options.headings | integer | 2 | Set the value of the headingLevel parameter in the header so markdown processors know how many heading levels to show in the table of contents. Currently supported only by Shins, not by Slate, which lacks this feature. |
--omitBody | options.omitBody | boolean | false | By default, Widdershins includes the body parameter as a row in the parameters table before the rows that represent the fields in the body. Set this parameter to omit that body parameter row. |
--omitHeader | options.omitHeader | boolean | false | Omit the header / YAML front-matter in the generated Markdown file. |
--resolve | options.resolve | boolean | false | Resolve external $refs, using the source parameter or the input file as the base location. |
--shallowSchemas | options.shallowSchemas | boolean | false | When referring to a schema with a $ref, don't show the full contents of the schema. |
N/A | options.source | string | None | The absolute location or URL of the source file to use as the base to resolve relative references ($refs) from; required if options.resolve is set to true. For CLI commands, Widdershins uses the input file as the base for the $refs. |
--summary | options.tocSummary | boolean | false | Use the operation summary as the TOC entry instead of the ID. |
--useBodyName | options.useBodyName | boolean | Use original param name for OpenAPI 2.0 body parameter. | |
-v, --verbose | options.verbose | boolean | false | Increase verbosity. |
-h, --help | options.help | boolean | false | Show help. |
--version | options.version | boolean | false | Show version number. |
-c, --code | options.codeSamples | boolean | false | Omit generated code samples. |
--httpsnippet | options.httpsnippet | boolean | false | Use httpsnippet to generate code samples. |
-d, --discovery | options.discovery | boolean | false | Include schema.org WebAPI discovery data. |
-e, --environment | N/A | string | None | File to load config options from. |
-i, --includes | options.includes | string | None | List of files to put in the include header of the output Markdown. Processors such as Shins can then import the contents of these files. |
-l, --lang | options.lang | boolean | false | Generate the list of languages for code samples based on the languages used in the source file's x-code-samples examples. |
--language_tabs | options.language_tabs | string | (Differs for each input type) | List of language tabs for code samples using language[:label[:client]] format, such as javascript:JavaScript:request . |
-m, --maxDepth | options.maxDepth | integer | 10 | Maximum depth to show for schema examples. |
-o, --outfile | N/A | string | None | File to write the output markdown to. If left blank, Widdershins sends the output to stdout. |
-r, --raw | inverse of options.sample | boolean | false | Output raw schemas instead of example values. |
-s, --search | options.search | boolean | true | Set the value of the search parameter in the header so Markdown processors like Slate include search or not in their output. |
-t, --theme | options.theme | string | darkula | Syntax-highlighter theme to use. |
-u, --user_templates | options.user_templates | string | None | Directory to load override templates from. |
-x, --experimental | options.experimental | boolean | Use httpSnippet for multipart mediatypes. | |
-y, --yaml | options.yaml | boolean | false | Display JSON schemas in YAML format. |
options.templateCallback | function | None | A function that is called before and after each template (JavaScript code only). | |
options.toc_footers | object | A map of url s and description s to be added to the ToC footers array (JavaScript code only). |
In Node.JS code, create an options object and pass it to the Widdershins convert
function, as in this example:
const converter = require('widdershins');
let options = {}; // defaults shown
options.codeSamples = true;
options.httpsnippet = false;
//options.language_tabs = [];
//options.language_clients = [];
//options.loadedFrom = sourceUrl; // only needed if input document is relative
//options.user_templates = './user_templates';
options.templateCallback = function(templateName,stage,data) { return data };
options.theme = 'darkula';
options.search = true;
options.sample = true; // set false by --raw
options.discovery = false;
options.includes = [];
options.shallowSchemas = false;
options.tocSummary = false;
options.headings = 2;
options.yaml = false;
//options.resolve = false;
//options.source = sourceUrl; // if resolve is true, must be set to full path or URL of the input document
converter.convert(apiObj,options)
.then(str => {
// str contains the converted markdown
})
.catch(err => {
console.error(err);
});
To only include a subset of the pre-defined language-tabs, or to rename their display-names, you can override the options.language_tabs
:
options.language_tabs = [{ 'go': 'Go' }, { 'http': 'HTTP' }, { 'javascript': 'JavaScript' }, { 'javascript--node': 'Node.JS' }, { 'python': 'Python' }, { 'ruby': 'Ruby' }];
The --environment
option specifies a JSON or YAML-formatted options
object, for example:
{
"language_tabs": [{ "go": "Go" }, { "http": "HTTP" }, { "javascript": "JavaScript" }, { "javascript--node": "Node.JS" }, { "python": "Python" }, { "ruby": "Ruby" }],
"verbose": true,
"tagGroups": [
{
"title": "Companies",
"tags": ["companies"]
},
{
"title": "Billing",
"tags": ["invoice-create", "invoice-close", "invoice-delete"]
}
]
}
You can also use the environment file to group OAS/Swagger tagged paths together to create a more elegant table of contents, and overall page structure.
If you need to support a version of Slate <v1.5.0 (or a renderer which also doesn't support display-names for language-tabs, such as node-slate
, slate-node
or whiteboard
), you can use the --environment
option with the included whiteboard_env.json
file to simply achieve this.
If you are using the httpsnippet
option to generate code samples, you can specify the client library used to perform the requests for each language by overriding the options.language_clients
:
options.language_clients = [{ 'shell': 'curl' }, { 'node': 'request' }, { 'java': 'unirest' }];
If the language name differs between the markdown name required to syntax highlight and the httpsnippet required target, both can be specified in the form markdown--target
.
To see the list of languages and clients supported by httpsnippet, click here.
The loadedFrom
option is only needed where the OpenAPI / Swagger definition does not specify a host, and (as per the OpenAPI specification) the API endpoint is deemed to be based on the source URL
the definition was loaded from.
To see the list of highlight-js syntax highlighting themes, click here.
Schema.org WebAPI discovery data is included if the discovery
option above is set true
. See the W3C WebAPI Discovery Community Group for more information.
Language tabs
Widdershins supports the x-code-samples
vendor-extension to completely customise your documentation. Alternatively, you can edit the default code-samples in the templates
sub-directory, or override them using the user_templates
option to specify a directory containing your templates.
Widdershins supports the use of multiple language tabs with the same language (i.e. plain Javascript and Node.Js). To use this support you must be using Slate (or one of its ports compatible with) version 1.5.0 or higher.
Templates
By default, Widdershins uses the templates in its templates/
folder to generate the Markdown output. To customize the templates, copy some or all of them to a folder and pass their location to the user_templates
parameter.
The templates include .dot
templates and .def
partials. To override a .dot
template, you must copy it and the child .def
partials that the template references. Similarly, to override a .def
partial, you must also copy the parent .dot
template. For OpenAPI 3, the primary template is main.dot
and its main child partials are parameters.def
, responses.def
, and callbacks.def
.
This means that it is usually easiest to copy all .dot
and .def
files to your user templates directory so you don't skip a template or partial. To bring in changes from Widdershins updates, you can use a visual diff
tool which can run across two directories, such as Meld or WinMerge.
Template syntax
Templates are compiled with doT.js.
Templates have access to a data
object with a range of properties based on the document context. For information about the parameters, see the README file for the appropriate templates:
- Swagger 2.0 / OpenAPI 3.0.x template parameters
- AsyncAPI 1.x template parameters
- Semoasa 0.1.0 template parameters
To print the value of a parameter or variable in a template, use the code {{=parameterName}}
. For example, to print the title of an OpenAPI 3 spec (from its info.title
field), use the code {{=data.api.info.title}}
.
To loop through values in an array, use the code {{~ arrayName :tempVariable}}
to start the loop and the code {{~}}
to close the loop. For example, the OpenAPI 3 partial parameters.def
uses this code to create a table of the parameters in an operation:
|Name|In|Type|Required|Description|
|---|---|---|---|---|
{{~ data.parameters :p}}|{{=p.name}}|{{=p.in}}|{{=p.safeType}}|{{=p.required}}|{{=p.shortDesc || 'none'}}|
{{~}}
For if/then logic, use the code {{? booleanExpression}}
to start the code block and the code {{?}}
to close the block. For example, the OpenAPI 3 main.dot
template calls the security.def
partial to show information about the security schemes if the OpenAPI spec includes a securitySchemes
section:
{{? data.api.components && data.api.components.securitySchemes }}
{{#def.security}}
{{?}}
You can run arbitrary JavaScript within a template by inserting a code block within curly braces. For example, this code creates a variable and references it with normal doT.js syntax later in the template:
{{ {
let message = "Hello!";
} }}
{{=message}}
Template callbacks
The templateCallback
parameter points to a function that Widdershins calls before and after each template runs. The callback function receives a data
object that contains the spec that Widdershins is processing; the function must return this object. You can use callback functions only if you are calling Widdershins from JavaScript code, not from the command line.
Widdershins passes these variables to the callback function:
templateName
: The name of the template, such asmain
.stage
: Whether Widdershins is calling the callback function before (pre
) or after (post
) the template.data
: An object that contains the data that Widdershins is processing. You can mutate thedata
object in any way you see fit, but the function must return it whether it changes it or not. Content that you put in thedata.append
property is appended to the current output stream.
For example, this JavaScript code prints the name of the template and the processing stage in the output Markdown:
'use strict';
const converter = require('widdershins');
const fs = require('fs');
let options = {};
options.templateCallback = myCallBackFunction;
function myCallBackFunction(templateName, stage, data) {
let statusString = "Template name: " + templateName + "\n";
statusString += "Stage: " + stage + "\n";
data.append = statusString;
return data;
}
const apiObj = JSON.parse(fs.readFileSync('defs/petstore3.json'));
converter.convert(apiObj, options)
.then(str => {
fs.writeFileSync('petstore3Output.md', str, 'utf8');
});
Tests
To run a test-suite:
node testRunner {path-to-APIs}
The test harness currently expects .yaml
or .json
files and has been tested against
Comparison between this and other OpenAPI / Swagger to Slate tools
Blog posting by the author of Widdershins.
Acknowledgements
- @latgeek for the logo.
- @vfernandestoptal for the httpsnippet support.
Widdershins in the wild
Please feel free to add a link to your API documentation here.
- GOV.UK Content API v1.0.0
- GOV UK Digital Marketplace API v1.0.0
- Capital One API
- Cognite Data API
- SpeckleWorks API
- Bank by API
- Open EO API
- Split Payments API
- LeApp daemon API
- Shutterstock API
- Shotstack Video Editing API
- Admetricks API
- Eqivo API
Widdershins and ReSlate
Widdershins
works well with Slate, but for a solely Node.js-based experience, why not try the ReSlate port?
Top Related Projects
Beautiful static documentation for your API
📘 OpenAPI/Swagger-generated API Reference Documentation
Build beautiful, interactive API Docs with embeddable React or Web Components, powered by OpenAPI and Markdown.
Swagger UI is a collection of HTML, JavaScript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API.
Easy OpenAPI specs and Swagger UI for your Flask API
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot