https://github.com/domeafavour/react-markdown
A lightweight, customizable React component for rendering Markdown content with TypeScript support and extensible rendering.
https://github.com/domeafavour/react-markdown
component markdown marked react typescript
Last synced: 5 months ago
JSON representation
A lightweight, customizable React component for rendering Markdown content with TypeScript support and extensible rendering.
- Host: GitHub
- URL: https://github.com/domeafavour/react-markdown
- Owner: domeafavour
- Created: 2025-10-10T06:02:28.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2025-10-16T05:48:01.000Z (9 months ago)
- Last Synced: 2025-10-17T08:04:05.496Z (9 months ago)
- Topics: component, markdown, marked, react, typescript
- Language: TypeScript
- Homepage: https://domeafavour.github.io/react-markdown/
- Size: 305 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# @domeadev/react-markdown
A lightweight, customizable React component for rendering Markdown content with TypeScript support and extensible rendering.
## Features
- 🚀 **Fast and Lightweight**: Built on top of [marked](https://marked.js.org/) for efficient parsing
- 🎨 **Fully Customizable**: Override any element renderer with custom React components
- 🔧 **TypeScript Support**: Full type safety with comprehensive TypeScript definitions
- 🧩 **Extensible**: Support for custom extensions and element types
- 📝 **GFM Support**: GitHub Flavored Markdown support out of the box
- 📚 **Storybook**: Interactive examples and documentation
## 📖 Documentation & Examples
**[View Live Storybook Documentation →](https://domeafavour.github.io/react-markdown/)**
Explore interactive examples, API documentation, and usage patterns in our Storybook deployment.
## Installation
### npm
```bash
npm install @domeadev/react-markdown
```
### yarn
```bash
yarn add @domeadev/react-markdown
```
### pnpm
```bash
pnpm add @domeadev/react-markdown
```
## Quick Start
```tsx
import { ReactMarkdown, useReactMarkdown } from "@domeadev/react-markdown";
function MyComponent() {
const markdown = `
# Hello World
This is **bold** text and this is *italic* text.
- List item 1
- List item 2
- [ ] Todo item
- [x] Completed item
[Link to example](https://example.com)
`;
const { elements, renders } = useReactMarkdown(markdown);
return ;
}
```
## API Reference
### useReactMarkdown Hook
The main hook for parsing markdown content.
```tsx
const { elements, renders } = useReactMarkdown(markdown, options);
```
#### Parameters
- `markdown` (string): The markdown content to parse
- `options` (optional): Configuration options
#### Options
```tsx
interface ReactMarkdownOptions {
/** Enable GitHub Flavored Markdown @default true */
gfm?: boolean;
/** Handle line breaks */
breaks?: boolean;
/** Custom extensions */
extensions?: ReactMarkdownExtension[];
/** Override default element renderers */
renders?: Partial;
}
```
### ReactMarkdown Component
The main component for rendering parsed markdown elements.
```tsx
```
#### Props
- `elements`: Parsed markdown elements from `useReactMarkdown`
- `renders`: Element renderers (default + custom overrides)
## Customizing Renderers
You can customize how any markdown element is rendered:
```tsx
import { ReactMarkdown, useReactMarkdown } from "@domeadev/react-markdown";
function CustomMarkdown() {
const markdown = "# Custom Heading\n\nThis is a **bold** paragraph.";
const { elements } = useReactMarkdown(markdown, {
renders: {
// Custom heading renderer
heading: ({ element, children }) => {
const headingElement = element as MarkdownHeadingElement;
return (
🎉 {children}
);
},
// Custom paragraph renderer
paragraph: ({ children }) => (
{children}
),
// Custom strong (bold) renderer
strong: ({ children }) => (
{children}
),
},
});
return ;
}
```
## Available Element Types
The following markdown elements are supported with default renderers:
| Element | Description | Custom Props |
| -------------- | ----------------------- | -------------------------------------- |
| `heading` | H1-H6 headings | `depth: 1-6` |
| `paragraph` | Paragraph text | - |
| `list` | Ordered/unordered lists | `ordered: boolean` |
| `list_item` | List items | `task: boolean`, `checked?: boolean` |
| `link` | Links | `href: string` |
| `image` | Images | `src: string`, `alt: string` |
| `code` | Code blocks | `lang?: string` |
| `codespan` | Inline code | - |
| `strong` | Bold text | - |
| `emphasis` | Italic text | - |
| `delete` | Strikethrough text | - |
| `blockquote` | Block quotes | - |
| `table` | Tables | `align: TableAlign[]` |
| `table_header` | Table header | - |
| `table_body` | Table body | - |
| `table_row` | Table row | - |
| `table_cell` | Table cell | `header: boolean`, `align: TableAlign` |
| `br` | Line break | - |
| `hr` | Horizontal rule | - |
| `text` | Plain text | - |
| `space` | Whitespace | - |
## Creating Extensions
You can create custom extensions to handle new markdown syntax:
```tsx
import { ReactMarkdownExtension } from "@domeadev/react-markdown";
// Example: Custom mention extension
const mentionExtension: ReactMarkdownExtension = {
name: "mention",
level: "inline",
start(src: string) {
return src.indexOf("@");
},
tokenizer(src: string) {
// Match @username pattern (letters, numbers, underscore, hyphen)
const rule = /^@([a-zA-Z0-9_-]+)/;
const match = rule.exec(src);
if (match) {
return {
type: "mention",
raw: match[0],
username: match[1],
};
}
return undefined;
},
parser: (token) => ({
type: "mention",
text: token.raw,
username: token.username,
}),
render: ({ element }) => @{element.username},
};
const { elements, renders } = useReactMarkdown(markdown, {
extensions: [mentionExtension],
});
```
## Advanced Usage
### With Custom Styling
```tsx
import { ReactMarkdown, useReactMarkdown } from "@domeadev/react-markdown";
import "./markdown-styles.css";
function StyledMarkdown({ content }: { content: string }) {
const { elements, renders } = useReactMarkdown(content, {
renders: {
heading: ({ element, children }) => {
const HeadingTag = `h${element.depth}` as keyof JSX.IntrinsicElements;
return (
{children}
);
},
code: ({ element }) => (
{element.text}
),
link: ({ element, children }) => (
{children}
),
},
});
return (
);
}
```
### With Task Lists
```tsx
function TaskListExample() {
const todoMarkdown = `
## My Todo List
- [x] Complete the documentation
- [x] Add TypeScript support
- [ ] Write more tests
- [ ] Add more examples
`;
const { elements, renders } = useReactMarkdown(todoMarkdown, {
renders: {
list_item: ({ element, children }) => (
{element.task && (
)}
{children}
),
},
});
return ;
}
```
## Development
### Build
```bash
pnpm build
```
### Test
```bash
pnpm test
```
### Storybook Development
Start the development server:
```bash
pnpm storybook
```
Build Storybook for production:
```bash
pnpm build-storybook
```
The Storybook documentation is automatically deployed to GitHub Pages on every push to the `main` branch.
### GitHub Pages Setup
For repository maintainers, the GitHub Pages deployment is handled automatically via GitHub Actions. To enable this:
1. Go to your repository's **Settings** → **Pages**
2. Set **Source** to "GitHub Actions"
3. The workflow will automatically deploy Storybook to `https://[username].github.io/[repository-name]/`
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## License
MIT
## Dependencies
- [marked](https://marked.js.org/) - Fast markdown parser
- [@domeadev/react-elements-renderer](https://github.com/domeafavour/react-elements-renderer) - Efficient React element rendering
## Related Packages
- `@domeadev/react-elements-renderer` - The underlying element rendering engine