API Reference

June 18, 2026 · View on GitHub

Core Function

quikdown(markdown, options?)

Converts markdown text to HTML.

Parameters

ParameterTypeRequiredDescription
markdownstringYesThe markdown text to convert
optionsobjectNoConfiguration options

Options

OptionTypeDefaultDescription
inline_stylesbooleanfalseUse inline styles instead of CSS classes
fence_pluginobjectundefinedCustom handler for fenced code blocks (object with .render method)
bidirectionalbooleanfalseAdd data-qd attributes for source tracking (v1.0.5+)
lazy_linefeedsbooleanfalseSingle newlines become <br> tags (v1.0.5+)
allow_unsafe_urlsbooleanfalseAllow javascript: and other potentially unsafe URLs
heading_idsbooleanfalseAdd id slug attributes to headings for anchor links
allow_unsafe_htmlboolean | string[] | objectfalseHTML passthrough control (v1.2.13+). false = escape all HTML (safe default). true = no escaping (trusted pipelines only). Array of tag names or object with tag keys = whitelist mode — listed tags pass through with sanitized attributes, all others are escaped. Event handler attributes (on*) are always stripped in whitelist mode. See Security Guide for details.
reference_linksbooleanfalseEnable reference-style links: [text][id], [text][], [id] with definitions [id]: url "title" (v1.2.20+)
footnotesbooleanfalseEnable footnotes: [^id] markers with [^id]: text definitions. Renders a footnotes section with back-links (v1.2.20+)

Returns

string - The converted HTML

Example

import quikdown from 'quikdown';

const markdown = '# Hello World\n\nThis is **bold** text.';
const html = quikdown(markdown);
console.log(html);
// <h1 class="quikdown-h1">Hello World</h1><p>This is <strong class="quikdown-strong">bold</strong> text.</p>

Configuration Methods

quikdown.configure(options)

Creates a pre-configured parser function with default options.

Parameters

ParameterTypeRequiredDescription
optionsobjectYesDefault configuration options

Returns

function - A configured parser function

Example

const myParser = quikdown.configure({
  inline_styles: true,
  fence_plugin: myPlugin
});

// Use the configured parser
const html = myParser('# Heading');
// No need to pass options each time

Style Methods

quikdown.emitStyles(prefix?, theme?)

Returns CSS styles for quikdown HTML output when not using inline styles.

Parameters

  • prefix (string, optional) - CSS class prefix. Default: 'quikdown-'
  • theme (string, optional) - Theme name: 'light' (default) or 'dark'

Returns

string - CSS stylesheet content with theme-appropriate colors

Example

// Generate light theme CSS
const lightStyles = quikdown.emitStyles('quikdown-', 'light');

// Generate dark theme CSS  
const darkStyles = quikdown.emitStyles('quikdown-', 'dark');

// Add to your page
const styleElement = document.createElement('style');
styleElement.textContent = lightStyles;
document.head.appendChild(styleElement);

// Or use pre-generated theme files
// dist/quikdown.light.css - Light theme with explicit colors
// dist/quikdown.dark.css - Dark theme with auto dark mode support

Theme Features

  • Container-based scoping: Use .quikdown-light or .quikdown-dark containers
  • Explicit colors: Both themes specify text colors for robustness
  • Auto dark mode: Dark CSS includes .quikdown-auto for system preferences
  • No conflicts: Multiple themes can coexist on the same page

Generated CSS Classes

.quikdown-h1 { margin-top: 0.5em; margin-bottom: 0.3em }
.quikdown-h2 { margin-top: 0.5em; margin-bottom: 0.3em }
.quikdown-h3 { margin-top: 0.5em; margin-bottom: 0.3em }
.quikdown-h4 { margin-top: 0.5em; margin-bottom: 0.3em }
.quikdown-h5 { margin-top: 0.5em; margin-bottom: 0.3em }
.quikdown-h6 { margin-top: 0.5em; margin-bottom: 0.3em }
.quikdown-pre { background: #f4f4f4; padding: 10px; border-radius: 4px; overflow-x: auto }
.quikdown-code { background: #f0f0f0; padding: 2px 4px; border-radius: 3px }
.quikdown-blockquote { border-left: 4px solid #ddd; margin-left: 0; padding-left: 1em; color: #666 }
.quikdown-table { border-collapse: collapse; width: 100%; margin: 1em 0 }
.quikdown-th { border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; font-weight: bold }
.quikdown-td { border: 1px solid #ddd; padding: 8px; text-align: left }
.quikdown-hr { border: none; border-top: 1px solid #ddd; margin: 1em 0 }
.quikdown-img { max-width: 100%; height: auto }
.quikdown-a { color: #0066cc; text-decoration: underline }
.quikdown-strong { font-weight: bold }
.quikdown-em { font-style: italic }
.quikdown-del { text-decoration: line-through }
.quikdown-ul { margin: 0.5em 0; padding-left: 2em }
.quikdown-ol { margin: 0.5em 0; padding-left: 2em }
.quikdown-li { margin: 0.25em 0 }

Properties

quikdown.version

The version of quikdown.

Type

string

Example

console.log(quikdown.version); // "1.2.17"

Fence Plugin API

Plugin Object Structure

interface FencePlugin {
  render: (content: string, language: string) => string | undefined;
  reverse?: (element: HTMLElement) => { fence: string; lang: string; content: string } | null;
}

render Parameters

ParameterTypeDescription
contentstringRaw, unescaped content of the code block
languagestringLanguage identifier (empty string if none)

render Returns

  • string - HTML to render
  • undefined - Use default code block rendering

reverse (optional)

Used by quikdown_bd to convert plugin-rendered HTML back to fenced code blocks.

Example

const syntaxHighlightPlugin = {
  render: (content, language) => {
    if (language && hljs.getLanguage(language)) {
      const highlighted = hljs.highlight(content, { language }).value;
      return `<pre class="hljs"><code class="language-${language}">${highlighted}</code></pre>`;
    }
    // Return undefined to use default rendering
    return undefined;
  }
};

const html = quikdown(markdown, {
  fence_plugin: syntaxHighlightPlugin
});

Plugin Examples

Mermaid Diagrams

const mermaidPlugin = {
  render: (content, language) => {
    if (language === 'mermaid') {
      const id = 'mermaid-' + Math.random().toString(36).substr(2, 9);
      // Render asynchronously after DOM insertion
      setTimeout(() => {
        mermaid.render(id + '-svg', content).then(result => {
          document.getElementById(id).innerHTML = result.svg;
        });
      }, 0);
      return `<div id="${id}" class="mermaid-diagram">Loading...</div>`;
    }
  }
};

Math Rendering

const mathPlugin = {
  render: (content, language) => {
    if (language === 'math' || language === 'latex') {
      return katex.renderToString(content, {
        throwOnError: false,
        displayMode: true
      });
    }
  }
};

Custom Components

const componentPlugin = {
  render: (content, language) => {
    if (language === 'component') {
      try {
        const config = JSON.parse(content);
        return renderComponent(config);
      } catch (e) {
        return `<div class="error">Invalid component: ${e.message}</div>`;
      }
    }
  }
};

Trusted HTML

const trustedHtmlPlugin = {
  render: (content, language) => {
    // Only allow from trusted sources!
    if (language === 'html-render' && isTrustedSource()) {
      return content; // Raw HTML - be careful!
    }
  }
};

Options Deep Dive

bidirectional Option

Enables preservation of original markdown syntax for HTML→Markdown conversion.

bidirectional: false (Default)

Standard HTML output without preservation attributes:

quikdown('**bold**', { bidirectional: false });
// Output: <strong class="quikdown-strong">bold</strong>

bidirectional: true

Adds data-qd attributes to preserve original markdown:

quikdown('**bold**', { bidirectional: true });
// Output: <strong class="quikdown-strong" data-qd="**">bold</strong>

Use when:

  • Building a markdown editor
  • Need HTML→Markdown conversion
  • Want to preserve exact markdown syntax
  • Using with quikdown_bd module

lazy_linefeeds Option

Enables lazy line break handling where single newlines become <br> tags.

lazy_linefeeds: false (Default)

Standard markdown behavior - only double spaces before newline create breaks:

quikdown('Line 1\nLine 2');
// Output: <p>Line 1\nLine 2</p>

quikdown('Line 1  \nLine 2');  // Two spaces before \n
// Output: <p>Line 1<br class="quikdown-br">Line 2</p>

lazy_linefeeds: true

Single newlines automatically become line breaks:

quikdown('Line 1\nLine 2', { lazy_linefeeds: true });
// Output: <p>Line 1<br class="quikdown-br">Line 2</p>

Perfect for:

  • Chat applications
  • LLM/AI output formatting
  • User-generated content where users expect Enter to create a new line
  • Converting informal text to HTML

Behavior:

  • Single \n<br> tag
  • Double \n\n → Paragraph break (unchanged)
  • Code blocks preserve newlines (no <br> conversion)
  • Lists maintain proper structure

Enables reference-style links where link definitions are separated from link usage.

Reference syntax passes through as plain text:

quikdown('[click here][example]\n\n[example]: https://example.com');
// Output: <p>[click here][example]</p><p>[example]: https://example.com</p>

Resolves reference patterns to <a> tags:

quikdown('[click here][example]\n\n[example]: https://example.com "Example Site"', {
  reference_links: true
});
// Output: <p><a href="https://example.com" title="Example Site">click here</a></p>

Supported syntax:

  • Full reference: [text][id]
  • Collapsed reference: [text][] (uses text as id)
  • Shortcut reference: [id] (uses id as both text and lookup)
  • Titles: "title", 'title', or (title) after URL
  • Angle-bracket URLs: [id]: <url>
  • Case-insensitive IDs
  • First definition wins (duplicates ignored)

Definition syntax:

[id]: url
[id]: url "title"
[id]: <url> 'title'

footnotes Option

Enables footnote markers and definitions with an auto-generated footnotes section.

footnotes: false (Default)

Footnote syntax passes through as plain text:

quikdown('Text[^1]\n\n[^1]: A footnote');
// Output: <p>Text[^1]</p><p>[^1]: A footnote</p>

footnotes: true

Renders footnote markers as superscript links and appends a footnotes section:

quikdown('Text[^1]\n\n[^1]: A footnote', { footnotes: true });
// Output: <p>Text<sup><a href="#fn-1" id="fnref-1">1</a></sup></p>
//         <section><hr><ol><li id="fn-1">A footnote <a href="#fnref-1">↩</a></li></ol></section>

Behavior:

  • Markers are numbered sequentially by first appearance
  • Same footnote referenced twice shows the same number
  • Unreferenced definitions are not rendered
  • Unresolved markers stay as plain text
  • Definitions support inline formatting (bold, italic, code, strikethrough)
  • Multi-line definitions use indented continuation lines

inline_styles Option

Controls how styling is applied to generated HTML.

inline_styles: false (Default)

Generates HTML with CSS classes:

quikdown('**bold**', { inline_styles: false });
// Output: <strong class="quikdown-strong">bold</strong>

Use when:

  • You have a stylesheet
  • You want consistent styling
  • You need to override styles
  • Page has multiple quikdown instances

inline_styles: true

Generates HTML with inline styles:

quikdown('**bold**', { inline_styles: true });
// Output: <strong style="font-weight: bold">bold</strong>

Use when:

  • Rendering in emails
  • No stylesheet access
  • Isolated components
  • Quick prototypes

Supported Markdown

Block Elements

ElementSyntaxExample
Heading 1-6# to ####### Heading
ParagraphDouble newlineText\n\nText
Blockquote> prefix> Quote
Code BlockTriple backticks```js\ncode\n```
Horizontal RuleThree+ hyphens---
Unordered List-, *, or +- Item
Ordered List1., 2., etc.1. Item
TablePipes and hyphens|A|B|

Inline Elements

ElementSyntaxExample
Bold** or __**bold**
Italic* or _*italic*
Strikethrough~~~~strike~~
CodeSingle backtick`code`
Link[text](url)[Google](https://google.com)
Image![alt](url)![Logo](logo.png)
Line BreakTwo spaces + newlineLine \nBreak
Reference Link[text][id][Google][goog] (requires reference_links: true)
Footnote[^id]See[^1] (requires footnotes: true)

Error Handling

quikdown is designed to be forgiving and never throw errors:

InputResult
null"" (empty string)
undefined"" (empty string)
Non-string"" (empty string)
Malformed markdownBest-effort HTML
Unclosed fenceTreated as regular text
Invalid tableRendered as plain text

Performance Tips

1. Reuse Configured Parsers

// ❌ Inefficient - options object created each time
for (const msg of messages) {
  html += quikdown(msg, { inline_styles: true });
}

// ✅ Efficient - reuse configured parser
const parser = quikdown.configure({ inline_styles: true });
for (const msg of messages) {
  html += parser(msg);
}

2. Cache Styles

// ❌ Generates styles repeatedly
function render() {
  return quikdown.emitStyles() + content;
}

// ✅ Generate once
const styles = quikdown.emitStyles();
function render() {
  return styles + content;
}

3. Batch Small Documents

// ❌ Many small parses
messages.forEach(msg => {
  container.innerHTML += quikdown(msg);
});

// ✅ Single parse
const combined = messages.join('\n\n---\n\n');
container.innerHTML = quikdown(combined);

Browser Compatibility

BrowserVersionNotes
Chrome61+Full support
Firefox60+Full support
Safari12+Full support
Edge79+Full support
IENot supported

Node.js Compatibility

VersionSupport
14.x✅ Full
16.x✅ Full
18.x✅ Full
20.x✅ Full

Module Comparison

Featurequikdownquikdown_bd
Markdown to HTML✅ Yes✅ Yes
HTML to Markdown❌ No✅ Yes
Size (minified)14.7KB19.5KB
toMarkdown() method❌ No✅ Yes
data-qd attributes❌ No✅ Yes
Use caseStandard parsingWYSIWYG editors

Bidirectional API

⚠️ Important: These methods are only available in the quikdown_bd module, NOT in regular quikdown.

quikdown_bd(markdown, options?)

Converts markdown to HTML with source tracking for bidirectional conversion. Only available when using quikdown_bd.

Parameters

ParameterTypeRequiredDescription
markdownstringYesThe markdown text to convert
optionsobjectNoConfiguration options

Options

OptionTypeDefaultDescription
inline_stylesbooleanfalseUse inline styles instead of CSS classes
fence_pluginobjectundefinedCustom handler for fenced code blocks (object with .render method)
bidirectionalbooleantrueAdd data-qd attributes for source tracking
lazy_linefeedsbooleanfalseSingle newlines become <br> tags (v1.0.5+)
reference_linksbooleanfalseEnable reference-style links (v1.2.20+)
footnotesbooleanfalseEnable footnotes (v1.2.20+)

Returns

string - HTML with data-qd attributes for source tracking

Example

import quikdown_bd from 'quikdown/bd';

const markdown = '**Hello** world';
const html = quikdown_bd(markdown, { bidirectional: true });
console.log(html);
// <strong data-qd="**" class="quikdown-strong">Hello</strong> world

quikdown_bd.toMarkdown(htmlOrElement)

Converts HTML back to Markdown using DOM walking and data-qd attributes.

Parameters

ParameterTypeRequiredDescription
htmlOrElementstring | HTMLElementYesHTML string or DOM element to convert

Returns

string - The reconstructed Markdown

Example

// From HTML string
const markdown = quikdown_bd.toMarkdown('<strong>bold</strong>');
console.log(markdown); // **bold**

// From DOM element
const element = document.getElementById('content');
const markdown = quikdown_bd.toMarkdown(element);

Browser Requirement

toMarkdown requires a DOM environment. In Node.js, use a library like jsdom:

const { JSDOM } = require('jsdom');
const dom = new JSDOM();
global.document = dom.window.document;
global.window = dom.window;
global.Node = dom.window.Node;

quikdown_bd.configure(options)

Creates a pre-configured bidirectional parser with default options.

Example

const myParser = quikdown_bd.configure({
  inline_styles: true,
  bidirectional: true
});

const html = myParser(markdown);

quikdown_bd.emitStyles(prefix?, theme?)

Returns CSS styles for bidirectional HTML output (currently returns empty string, reserved for future use).

quikdown_bd.version

Returns the version string of the quikdown_bd module.

Module Formats

quikdown is distributed in multiple formats:

Core Module

FormatFileUsage
UMDdist/quikdown.umd.jsBrowser script tag
UMD minifieddist/quikdown.umd.min.jsProduction browser
ESMdist/quikdown.esm.jsES6 imports
ESM minifieddist/quikdown.esm.min.jsProduction ES6
CommonJSdist/quikdown.cjsNode.js require()

Bidirectional Module

FormatFileUsage
UMDdist/quikdown_bd.umd.jsBrowser script tag
UMD minifieddist/quikdown_bd.umd.min.jsProduction browser
ESMdist/quikdown_bd.esm.jsES6 imports
ESM minifieddist/quikdown_bd.esm.min.jsProduction ES6
CommonJSdist/quikdown_bd.cjsNode.js require()

AST Libraries

For structured data output, quikdown provides AST (Abstract Syntax Tree) libraries:

quikdown_ast(markdown, options?)

Parses markdown into an AST object.

import quikdown_ast from 'quikdown/ast';

const ast = quikdown_ast('# Hello **world**');
// { type: 'document', children: [{ type: 'heading', level: 1, ... }] }

quikdown_json(markdown, options?)

Converts markdown to a JSON string.

import quikdown_json from 'quikdown/json';

const json = quikdown_json('# Hello', { indent: 2 });

quikdown_yaml(markdown, options?)

Converts markdown to a YAML string.

import quikdown_yaml from 'quikdown/yaml';

const yaml = quikdown_yaml('# Hello');

quikdown_ast_html(input, options?)

Renders AST, JSON, YAML, or markdown to HTML.

import quikdown_ast_html from 'quikdown/ast-html';

const html = quikdown_ast_html(ast);  // or json/yaml string

See AST Documentation for complete node type reference.

AST Module Formats

FormatFileUsage
ESMdist/quikdown_ast.esm.jsES6 imports
UMDdist/quikdown_ast.umd.min.jsBrowser
CommonJSdist/quikdown_ast.cjsNode.js

Similar formats available for quikdown_json, quikdown_yaml, and quikdown_ast_html.

TypeScript

TypeScript definitions are included for all modules:

declare module 'quikdown' {
  interface FencePlugin {
    render: (content: string, language: string) => string | undefined;
    reverse?: (element: HTMLElement) => {
      fence: string;
      lang: string;
      content: string;
    } | null;
  }

  interface QuikdownOptions {
    inline_styles?: boolean;
    fence_plugin?: FencePlugin;
    bidirectional?: boolean;
    lazy_linefeeds?: boolean;
    allow_unsafe_urls?: boolean;
    heading_ids?: boolean;
    reference_links?: boolean;
    footnotes?: boolean;
  }
  
  interface QuikdownFunction {
    (markdown: string, options?: QuikdownOptions): string;
    configure(options: QuikdownOptions): (markdown: string) => string;
    emitStyles(prefix?: string, theme?: 'light' | 'dark'): string;
    version: string;
  }
  
  const quikdown: QuikdownFunction;
  export default quikdown;
}