Convert markdown to JSX with ease for React and React-like projects.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Advanced parsing options including custom createElement behavior, HTML parsing control, and heading formatting rules.
Override React's createElement function to customize how all elements are created and rendered.
/**
* Custom element creation function
* Called for every JSX element created by the compiler
*/
type CreateElementFunction = (
tag: Parameters<React.createElement>[0],
props: React.JSX.IntrinsicAttributes,
...children: React.ReactNode[]
) => React.ReactNode;
interface CreateElementOptions {
createElement?: CreateElementFunction;
}Usage Examples:
import { compiler } from "markdown-to-jsx";
import { createElement } from "react";
// Custom createElement with global props injection
const customCreateElement = (tag, props, ...children) => {
// Add data attributes to all elements
const enhancedProps = {
...props,
'data-markdown': 'true',
'data-tag': typeof tag === 'string' ? tag : tag.name
};
return createElement(tag, enhancedProps, ...children);
};
// Custom createElement with element tracking
const trackingCreateElement = (tag, props, ...children) => {
// Track which elements are being created
console.log(`Creating element: ${tag}`, props);
return createElement(tag, props, ...children);
};
// Custom createElement for different React-like libraries
const preactCreateElement = (tag, props, ...children) => {
// Adapt for Preact or other React-like libraries
return h(tag, props, ...children);
};
const options = {
createElement: customCreateElement
};
const result = compiler("# Hello **World**", options);Control how raw HTML in markdown is processed and converted to JSX.
interface HTMLParsingOptions {
/** Disable parsing of raw HTML tags into JSX */
disableParsingRawHTML?: boolean;
}Usage Examples:
// Allow HTML parsing (default behavior)
const htmlContent = `
# Title
<div class="custom">
This **markdown** works inside HTML.
<span style="color: red;">Styled text</span>
</div>
Regular markdown continues.
`;
const withHTML = compiler(htmlContent, {
disableParsingRawHTML: false // default
});
// Disable HTML parsing (treat as literal text)
const withoutHTML = compiler(htmlContent, {
disableParsingRawHTML: true
});
// HTML tags become literal text instead of JSX elements
// Security consideration - disable HTML for untrusted content
const userContent = getUserMarkdown(); // potentially unsafe
const safeResult = compiler(userContent, {
disableParsingRawHTML: true // prevents HTML injection
});Control automatic conversion of URLs to clickable links.
interface AutoLinkOptions {
/** Disable automatic URL linking */
disableAutoLink?: boolean;
}Usage Examples:
const contentWithURLs = `
Check out https://example.com for more info.
Also see http://another-site.com and https://third-site.com.
`;
// With auto-linking (default)
const withLinks = compiler(contentWithURLs, {
disableAutoLink: false // default
});
// URLs become clickable <a> tags
// Without auto-linking
const withoutLinks = compiler(contentWithURLs, {
disableAutoLink: true
});
// URLs remain as plain textEnforce strict CommonMark compliance for heading syntax.
interface HeadingOptions {
/** Require space after # characters in ATX headings */
enforceAtxHeadings?: boolean;
}Usage Examples:
const headingContent = `
#NoSpace
# With Space
##AlsoNoSpace
## Also With Space
`;
// Lenient parsing (default)
const lenient = compiler(headingContent, {
enforceAtxHeadings: false // default
});
// Both styles work: "#NoSpace" and "# With Space"
// Strict CommonMark compliance
const strict = compiler(headingContent, {
enforceAtxHeadings: true
});
// Only "# With Space" becomes heading, "#NoSpace" remains textControl how content is wrapped in container elements.
interface WrapperOptions {
/** Force block-level wrapper regardless of content */
forceBlock?: boolean;
/** Force inline wrapper regardless of content */
forceInline?: boolean;
/** Always wrap content even for single elements */
forceWrapper?: boolean;
/** Custom wrapper element type or null for no wrapper */
wrapper?: React.ElementType | null;
}Usage Examples:
const singleParagraph = "Just a simple paragraph.";
const multipleElements = "# Title\n\nParagraph content.";
// Force block wrapper
const forceBlock = compiler(singleParagraph, {
forceBlock: true
});
// Wrapped in <div> even though content is inline
// Force inline wrapper
const forceInline = compiler(multipleElements, {
forceInline: true
});
// Wrapped in <span> even though content has block elements
// Always force wrapper
const alwaysWrap = compiler(singleParagraph, {
forceWrapper: true
});
// Single paragraph still gets wrapper element
// Custom wrapper element
const customWrapper = compiler(multipleElements, {
wrapper: "article"
});
// Content wrapped in <article> instead of <div>
// No wrapper (returns array)
const noWrapper = compiler(multipleElements, {
wrapper: null
});
// Returns [<h1>...</h1>, <p>...</p>] instead of wrapped content
// React Fragment wrapper
const fragmentWrapper = compiler(multipleElements, {
wrapper: React.Fragment
});
// Wrapped in <React.Fragment>Customize HTML entity to Unicode character mappings.
interface EntityOptions {
/** Custom HTML entity mappings */
namedCodesToUnicode?: { [key: string]: string };
}Usage Examples:
const contentWithEntities = `
Standard entities: & < > " '
Custom entities: &heart; ☆ &arrow;
`;
// Default entity mappings
const defaultEntities = compiler(contentWithEntities);
// Only standard entities are decoded
// Custom entity mappings
const customEntities = compiler(contentWithEntities, {
namedCodesToUnicode: {
// Extend default mappings
heart: "❤️",
star: "⭐",
arrow: "→",
// Override defaults
amp: "&", // Use full-width ampersand
}
});
// Custom entities are decoded along with defaultsCombine multiple advanced options for complex use cases.
Usage Examples:
import { compiler } from "markdown-to-jsx";
import { trackElementCreation } from "./analytics";
const advancedOptions = {
// Custom element creation with analytics
createElement: (tag, props, ...children) => {
trackElementCreation(tag, props);
return React.createElement(tag, props, ...children);
},
// Security settings
disableParsingRawHTML: true,
disableAutoLink: false,
// Strict markdown compliance
enforceAtxHeadings: true,
// Custom wrapper for semantic HTML
wrapper: "main",
forceWrapper: true,
// Extended entity support
namedCodesToUnicode: {
copyright: "©",
trademark: "™",
registered: "®"
}
};
const secureResult = compiler(userMarkdownContent, advancedOptions);