{"id":44060179,"url":"https://github.com/domeafavour/react-markdown","last_synced_at":"2026-02-08T01:30:45.282Z","repository":{"id":319034732,"uuid":"1073444767","full_name":"domeafavour/react-markdown","owner":"domeafavour","description":"A lightweight, customizable React component for rendering Markdown content with TypeScript support and extensible rendering.","archived":false,"fork":false,"pushed_at":"2025-10-16T05:48:01.000Z","size":312,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-17T08:04:05.496Z","etag":null,"topics":["component","markdown","marked","react","typescript"],"latest_commit_sha":null,"homepage":"https://domeafavour.github.io/react-markdown/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/domeafavour.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-10T06:02:28.000Z","updated_at":"2025-10-16T05:46:45.000Z","dependencies_parsed_at":"2025-10-17T21:01:02.570Z","dependency_job_id":"1adc2329-6797-421a-8625-2cd50294876a","html_url":"https://github.com/domeafavour/react-markdown","commit_stats":null,"previous_names":["domeafavour/react-markdown"],"tags_count":2,"template":false,"template_full_name":"domeafavour/react-hook-package-template","purl":"pkg:github/domeafavour/react-markdown","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domeafavour%2Freact-markdown","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domeafavour%2Freact-markdown/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domeafavour%2Freact-markdown/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domeafavour%2Freact-markdown/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/domeafavour","download_url":"https://codeload.github.com/domeafavour/react-markdown/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domeafavour%2Freact-markdown/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29216084,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-08T00:10:47.190Z","status":"ssl_error","status_checked_at":"2026-02-08T00:10:43.589Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["component","markdown","marked","react","typescript"],"created_at":"2026-02-08T01:30:44.692Z","updated_at":"2026-02-08T01:30:45.276Z","avatar_url":"https://github.com/domeafavour.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @domeadev/react-markdown\n\nA lightweight, customizable React component for rendering Markdown content with TypeScript support and extensible rendering.\n\n## Features\n\n- 🚀 **Fast and Lightweight**: Built on top of [marked](https://marked.js.org/) for efficient parsing\n- 🎨 **Fully Customizable**: Override any element renderer with custom React components\n- 🔧 **TypeScript Support**: Full type safety with comprehensive TypeScript definitions\n- 🧩 **Extensible**: Support for custom extensions and element types\n- 📝 **GFM Support**: GitHub Flavored Markdown support out of the box\n- 📚 **Storybook**: Interactive examples and documentation\n\n## 📖 Documentation \u0026 Examples\n\n**[View Live Storybook Documentation →](https://domeafavour.github.io/react-markdown/)**\n\nExplore interactive examples, API documentation, and usage patterns in our Storybook deployment.\n\n## Installation\n\n### npm\n\n```bash\nnpm install @domeadev/react-markdown\n```\n\n### yarn\n\n```bash\nyarn add @domeadev/react-markdown\n```\n\n### pnpm\n\n```bash\npnpm add @domeadev/react-markdown\n```\n\n## Quick Start\n\n```tsx\nimport { ReactMarkdown, useReactMarkdown } from \"@domeadev/react-markdown\";\n\nfunction MyComponent() {\n  const markdown = `\n# Hello World\n\nThis is **bold** text and this is *italic* text.\n\n- List item 1\n- List item 2\n- [ ] Todo item\n- [x] Completed item\n\n[Link to example](https://example.com)\n  `;\n\n  const { elements, renders } = useReactMarkdown(markdown);\n\n  return \u003cReactMarkdown elements={elements} renders={renders} /\u003e;\n}\n```\n\n## API Reference\n\n### useReactMarkdown Hook\n\nThe main hook for parsing markdown content.\n\n```tsx\nconst { elements, renders } = useReactMarkdown(markdown, options);\n```\n\n#### Parameters\n\n- `markdown` (string): The markdown content to parse\n- `options` (optional): Configuration options\n\n#### Options\n\n```tsx\ninterface ReactMarkdownOptions {\n  /** Enable GitHub Flavored Markdown @default true */\n  gfm?: boolean;\n  /** Handle line breaks */\n  breaks?: boolean;\n  /** Custom extensions */\n  extensions?: ReactMarkdownExtension[];\n  /** Override default element renderers */\n  renders?: Partial\u003cDefaultElementRenders\u003e;\n}\n```\n\n### ReactMarkdown Component\n\nThe main component for rendering parsed markdown elements.\n\n```tsx\n\u003cReactMarkdown elements={elements} renders={renders} /\u003e\n```\n\n#### Props\n\n- `elements`: Parsed markdown elements from `useReactMarkdown`\n- `renders`: Element renderers (default + custom overrides)\n\n## Customizing Renderers\n\nYou can customize how any markdown element is rendered:\n\n```tsx\nimport { ReactMarkdown, useReactMarkdown } from \"@domeadev/react-markdown\";\n\nfunction CustomMarkdown() {\n  const markdown = \"# Custom Heading\\n\\nThis is a **bold** paragraph.\";\n\n  const { elements } = useReactMarkdown(markdown, {\n    renders: {\n      // Custom heading renderer\n      heading: ({ element, children }) =\u003e {\n        const headingElement = element as MarkdownHeadingElement;\n        return (\n          \u003ch1 className={`custom-h${headingElement.depth}`}\u003e🎉 {children}\u003c/h1\u003e\n        );\n      },\n      // Custom paragraph renderer\n      paragraph: ({ children }) =\u003e (\n        \u003cp className=\"custom-paragraph\"\u003e{children}\u003c/p\u003e\n      ),\n      // Custom strong (bold) renderer\n      strong: ({ children }) =\u003e (\n        \u003cspan className=\"font-bold text-blue-600\"\u003e{children}\u003c/span\u003e\n      ),\n    },\n  });\n\n  return \u003cReactMarkdown elements={elements} renders={renders} /\u003e;\n}\n```\n\n## Available Element Types\n\nThe following markdown elements are supported with default renderers:\n\n| Element        | Description             | Custom Props                           |\n| -------------- | ----------------------- | -------------------------------------- |\n| `heading`      | H1-H6 headings          | `depth: 1-6`                           |\n| `paragraph`    | Paragraph text          | -                                      |\n| `list`         | Ordered/unordered lists | `ordered: boolean`                     |\n| `list_item`    | List items              | `task: boolean`, `checked?: boolean`   |\n| `link`         | Links                   | `href: string`                         |\n| `image`        | Images                  | `src: string`, `alt: string`           |\n| `code`         | Code blocks             | `lang?: string`                        |\n| `codespan`     | Inline code             | -                                      |\n| `strong`       | Bold text               | -                                      |\n| `emphasis`     | Italic text             | -                                      |\n| `delete`       | Strikethrough text      | -                                      |\n| `blockquote`   | Block quotes            | -                                      |\n| `table`        | Tables                  | `align: TableAlign[]`                  |\n| `table_header` | Table header            | -                                      |\n| `table_body`   | Table body              | -                                      |\n| `table_row`    | Table row               | -                                      |\n| `table_cell`   | Table cell              | `header: boolean`, `align: TableAlign` |\n| `br`           | Line break              | -                                      |\n| `hr`           | Horizontal rule         | -                                      |\n| `text`         | Plain text              | -                                      |\n| `space`        | Whitespace              | -                                      |\n\n## Creating Extensions\n\nYou can create custom extensions to handle new markdown syntax:\n\n```tsx\nimport { ReactMarkdownExtension } from \"@domeadev/react-markdown\";\n\n// Example: Custom mention extension\nconst mentionExtension: ReactMarkdownExtension = {\n  name: \"mention\",\n  level: \"inline\",\n  start(src: string) {\n    return src.indexOf(\"@\");\n  },\n  tokenizer(src: string) {\n    // Match @username pattern (letters, numbers, underscore, hyphen)\n    const rule = /^@([a-zA-Z0-9_-]+)/;\n    const match = rule.exec(src);\n\n    if (match) {\n      return {\n        type: \"mention\",\n        raw: match[0],\n        username: match[1],\n      };\n    }\n    return undefined;\n  },\n  parser: (token) =\u003e ({\n    type: \"mention\",\n    text: token.raw,\n    username: token.username,\n  }),\n  render: ({ element }) =\u003e \u003cspan className=\"mention\"\u003e@{element.username}\u003c/span\u003e,\n};\n\nconst { elements, renders } = useReactMarkdown(markdown, {\n  extensions: [mentionExtension],\n});\n```\n\n## Advanced Usage\n\n### With Custom Styling\n\n```tsx\nimport { ReactMarkdown, useReactMarkdown } from \"@domeadev/react-markdown\";\nimport \"./markdown-styles.css\";\n\nfunction StyledMarkdown({ content }: { content: string }) {\n  const { elements, renders } = useReactMarkdown(content, {\n    renders: {\n      heading: ({ element, children }) =\u003e {\n        const HeadingTag = `h${element.depth}` as keyof JSX.IntrinsicElements;\n        return (\n          \u003cHeadingTag className={`heading-${element.depth} mb-4 font-bold`}\u003e\n            {children}\n          \u003c/HeadingTag\u003e\n        );\n      },\n      code: ({ element }) =\u003e (\n        \u003cpre className=\"bg-gray-100 p-4 rounded-lg overflow-x-auto\"\u003e\n          \u003ccode className={`language-${element.lang || \"text\"}`}\u003e\n            {element.text}\n          \u003c/code\u003e\n        \u003c/pre\u003e\n      ),\n      link: ({ element, children }) =\u003e (\n        \u003ca\n          href={element.href}\n          className=\"text-blue-600 hover:text-blue-800 underline\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        \u003e\n          {children}\n        \u003c/a\u003e\n      ),\n    },\n  });\n\n  return (\n    \u003cdiv className=\"prose prose-lg max-w-none\"\u003e\n      \u003cReactMarkdown elements={elements} renders={renders} /\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n### With Task Lists\n\n```tsx\nfunction TaskListExample() {\n  const todoMarkdown = `\n## My Todo List\n\n- [x] Complete the documentation\n- [x] Add TypeScript support\n- [ ] Write more tests\n- [ ] Add more examples\n  `;\n\n  const { elements, renders } = useReactMarkdown(todoMarkdown, {\n    renders: {\n      list_item: ({ element, children }) =\u003e (\n        \u003cli className=\"flex items-center gap-2\"\u003e\n          {element.task \u0026\u0026 (\n            \u003cinput\n              type=\"checkbox\"\n              checked={element.checked}\n              className=\"form-checkbox h-4 w-4 text-blue-600\"\n              readOnly\n            /\u003e\n          )}\n          \u003cspan className={element.checked ? \"line-through text-gray-500\" : \"\"}\u003e\n            {children}\n          \u003c/span\u003e\n        \u003c/li\u003e\n      ),\n    },\n  });\n\n  return \u003cReactMarkdown elements={elements} renders={renders} /\u003e;\n}\n```\n\n## Development\n\n### Build\n\n```bash\npnpm build\n```\n\n### Test\n\n```bash\npnpm test\n```\n\n### Storybook Development\n\nStart the development server:\n\n```bash\npnpm storybook\n```\n\nBuild Storybook for production:\n\n```bash\npnpm build-storybook\n```\n\nThe Storybook documentation is automatically deployed to GitHub Pages on every push to the `main` branch.\n\n### GitHub Pages Setup\n\nFor repository maintainers, the GitHub Pages deployment is handled automatically via GitHub Actions. To enable this:\n\n1. Go to your repository's **Settings** → **Pages**\n2. Set **Source** to \"GitHub Actions\"\n3. The workflow will automatically deploy Storybook to `https://[username].github.io/[repository-name]/`\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nMIT\n\n## Dependencies\n\n- [marked](https://marked.js.org/) - Fast markdown parser\n- [@domeadev/react-elements-renderer](https://github.com/domeafavour/react-elements-renderer) - Efficient React element rendering\n\n## Related Packages\n\n- `@domeadev/react-elements-renderer` - The underlying element rendering engine\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdomeafavour%2Freact-markdown","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdomeafavour%2Freact-markdown","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdomeafavour%2Freact-markdown/lists"}