API Reference
June 18, 2026 · View on GitHub
Core Function
quikdown(markdown, options?)
Converts markdown text to HTML.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
markdown | string | Yes | The markdown text to convert |
options | object | No | Configuration options |
Options
| Option | Type | Default | Description |
|---|---|---|---|
inline_styles | boolean | false | Use inline styles instead of CSS classes |
fence_plugin | object | undefined | Custom handler for fenced code blocks (object with .render method) |
bidirectional | boolean | false | Add data-qd attributes for source tracking (v1.0.5+) |
lazy_linefeeds | boolean | false | Single newlines become <br> tags (v1.0.5+) |
allow_unsafe_urls | boolean | false | Allow javascript: and other potentially unsafe URLs |
heading_ids | boolean | false | Add id slug attributes to headings for anchor links |
allow_unsafe_html | boolean | string[] | object | false | HTML 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_links | boolean | false | Enable reference-style links: [text][id], [text][], [id] with definitions [id]: url "title" (v1.2.20+) |
footnotes | boolean | false | Enable 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
| Parameter | Type | Required | Description |
|---|---|---|---|
options | object | Yes | Default 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-lightor.quikdown-darkcontainers - Explicit colors: Both themes specify text colors for robustness
- Auto dark mode: Dark CSS includes
.quikdown-autofor 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
| Parameter | Type | Description |
|---|---|---|
content | string | Raw, unescaped content of the code block |
language | string | Language identifier (empty string if none) |
render Returns
string- HTML to renderundefined- 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_bdmodule
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
reference_links Option
Enables reference-style links where link definitions are separated from link usage.
reference_links: false (Default)
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>
reference_links: true
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
| Element | Syntax | Example |
|---|---|---|
| Heading 1-6 | # to ###### | # Heading |
| Paragraph | Double newline | Text\n\nText |
| Blockquote | > prefix | > Quote |
| Code Block | Triple backticks | ```js\ncode\n``` |
| Horizontal Rule | Three+ hyphens | --- |
| Unordered List | -, *, or + | - Item |
| Ordered List | 1., 2., etc. | 1. Item |
| Table | Pipes and hyphens | |A|B| |
Inline Elements
| Element | Syntax | Example |
|---|---|---|
| Bold | ** or __ | **bold** |
| Italic | * or _ | *italic* |
| Strikethrough | ~~ | ~~strike~~ |
| Code | Single backtick | `code` |
| Link | [text](url) | [Google](https://google.com) |
| Image |  |  |
| Line Break | Two spaces + newline | Line \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:
| Input | Result |
|---|---|
null | "" (empty string) |
undefined | "" (empty string) |
| Non-string | "" (empty string) |
| Malformed markdown | Best-effort HTML |
| Unclosed fence | Treated as regular text |
| Invalid table | Rendered 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
| Browser | Version | Notes |
|---|---|---|
| Chrome | 61+ | Full support |
| Firefox | 60+ | Full support |
| Safari | 12+ | Full support |
| Edge | 79+ | Full support |
| IE | ❌ | Not supported |
Node.js Compatibility
| Version | Support |
|---|---|
| 14.x | ✅ Full |
| 16.x | ✅ Full |
| 18.x | ✅ Full |
| 20.x | ✅ Full |
Module Comparison
| Feature | quikdown | quikdown_bd |
|---|---|---|
| Markdown to HTML | ✅ Yes | ✅ Yes |
| HTML to Markdown | ❌ No | ✅ Yes |
| Size (minified) | 14.7KB | 19.5KB |
toMarkdown() method | ❌ No | ✅ Yes |
| data-qd attributes | ❌ No | ✅ Yes |
| Use case | Standard parsing | WYSIWYG 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
| Parameter | Type | Required | Description |
|---|---|---|---|
markdown | string | Yes | The markdown text to convert |
options | object | No | Configuration options |
Options
| Option | Type | Default | Description |
|---|---|---|---|
inline_styles | boolean | false | Use inline styles instead of CSS classes |
fence_plugin | object | undefined | Custom handler for fenced code blocks (object with .render method) |
bidirectional | boolean | true | Add data-qd attributes for source tracking |
lazy_linefeeds | boolean | false | Single newlines become <br> tags (v1.0.5+) |
reference_links | boolean | false | Enable reference-style links (v1.2.20+) |
footnotes | boolean | false | Enable 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
| Parameter | Type | Required | Description |
|---|---|---|---|
htmlOrElement | string | HTMLElement | Yes | HTML 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
| Format | File | Usage |
|---|---|---|
| UMD | dist/quikdown.umd.js | Browser script tag |
| UMD minified | dist/quikdown.umd.min.js | Production browser |
| ESM | dist/quikdown.esm.js | ES6 imports |
| ESM minified | dist/quikdown.esm.min.js | Production ES6 |
| CommonJS | dist/quikdown.cjs | Node.js require() |
Bidirectional Module
| Format | File | Usage |
|---|---|---|
| UMD | dist/quikdown_bd.umd.js | Browser script tag |
| UMD minified | dist/quikdown_bd.umd.min.js | Production browser |
| ESM | dist/quikdown_bd.esm.js | ES6 imports |
| ESM minified | dist/quikdown_bd.esm.min.js | Production ES6 |
| CommonJS | dist/quikdown_bd.cjs | Node.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
| Format | File | Usage |
|---|---|---|
| ESM | dist/quikdown_ast.esm.js | ES6 imports |
| UMD | dist/quikdown_ast.umd.min.js | Browser |
| CommonJS | dist/quikdown_ast.cjs | Node.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;
}