{"id":13624170,"url":"https://github.com/remarkjs/react-remark","last_synced_at":"2025-06-10T21:19:23.728Z","repository":{"id":42571793,"uuid":"264682550","full_name":"remarkjs/react-remark","owner":"remarkjs","description":"React component and hook to use remark to render markdown","archived":false,"fork":false,"pushed_at":"2025-05-28T12:34:26.000Z","size":4066,"stargazers_count":223,"open_issues_count":14,"forks_count":9,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-05-28T13:35:25.268Z","etag":null,"topics":["markdown","react","react-components","react-hooks","rehype","remark","unified"],"latest_commit_sha":null,"homepage":"https://remarkjs.github.io/react-remark","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/remarkjs.png","metadata":{"funding":{"github":"unifiedjs","open_collective":"unified"},"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2020-05-17T14:13:44.000Z","updated_at":"2025-05-26T14:04:22.000Z","dependencies_parsed_at":"2024-01-07T21:05:04.752Z","dependency_job_id":"5203c3e4-4d97-4095-b8ad-8c5622e440d4","html_url":"https://github.com/remarkjs/react-remark","commit_stats":{"total_commits":78,"total_committers":4,"mean_commits":19.5,"dds":"0.21794871794871795","last_synced_commit":"39553e5f5c9e9b903bebf261788ff45130668de0"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remarkjs%2Freact-remark","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remarkjs%2Freact-remark/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remarkjs%2Freact-remark/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remarkjs%2Freact-remark/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/remarkjs","download_url":"https://codeload.github.com/remarkjs/react-remark/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remarkjs%2Freact-remark/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259152784,"owners_count":22813227,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["markdown","react","react-components","react-hooks","rehype","remark","unified"],"created_at":"2024-08-01T21:01:39.723Z","updated_at":"2025-06-10T21:19:23.437Z","avatar_url":"https://github.com/remarkjs.png","language":"TypeScript","funding_links":["https://github.com/sponsors/unifiedjs","https://opencollective.com/unified"],"categories":["TypeScript"],"sub_categories":[],"readme":"# react-remark\n\n[![CI](https://github.com/remarkjs/react-remark/workflows/CI/badge.svg?branch=main)](https://github.com/remarkjs/react-remark/actions?query=workflow%3ACI)\n[![Downloads](https://img.shields.io/npm/dm/react-remark.svg)](https://www.npmjs.com/package/react-remark)\n[![Size](https://img.shields.io/bundlephobia/minzip/react-remark.svg)](https://bundlephobia.com/result?p=react-remark)\n\n**react-remark** offers a [React hook](https://reactjs.org/docs/hooks-intro.html) and [React component](https://reactjs.org/docs/glossary.html#components) based way of rendering [markdown](https://commonmark.org/) into [React](https://reactjs.org) using [remark](https://github.com/remarkjs/remark)\n\n## Installation\n\n_npm_\n\n```\nnpm install --save react-remark\n```\n\n_yarn_\n\n```\nyarn add react-remark\n```\n\n## Usage\n\n### As a hook\n\n#### Render static content\n\n```tsx\nimport React, { useEffect } from 'react';\nimport { useRemark } from 'react-remark';\n\nconst ExampleComponent = () =\u003e {\n  const [reactContent, setMarkdownSource] = useRemark();\n\n  useEffect(() =\u003e {\n    setMarkdownSource('# markdown header');\n  }, []);\n\n  return reactContent;\n};\n\nexport default ExampleComponent;\n```\n\n#### Using input and events to update\n\n```tsx\nimport React from 'react';\nimport { useRemark } from 'react-remark';\n\nconst ExampleComponent = () =\u003e {\n  const [reactContent, setMarkdownSource] = useRemark();\n\n  return (\n    \u003c\u003e\n      \u003cinput\n        type=\"text\"\n        onChange={({ currentTarget }) =\u003e setMarkdownSource(currentTarget.value)}\n      /\u003e\n      {reactContent}\n    \u003c/\u003e\n  );\n};\n\nexport default ExampleComponent;\n```\n\n### Server side rendering\n\n```tsx\nimport React from 'react';\nimport { useRemarkSync } from 'react-remark';\n\nconst ExampleComponent = () =\u003e {\n  const reactContent = useRemarkSync('# markdown header');\n\n  return reactContent;\n};\n\nexport default ExampleComponent;\n```\n\n:notebook: Note that some remark plugins are async, these plugins will error if used with `useRemarkSync`.\n\n[More examples of usage as hook in storybook.](https://remarkjs.github.io/react-remark/?path=/story/remark-hook)\n\n### As a component\n\n#### Render static content\n\n```tsx\nimport React, { useState } from 'react';\nimport { Remark } from 'react-remark';\n\nconst ExampleComponent = () =\u003e (\n  \u003cRemark\u003e{`\n# header\n\n1. ordered\n2. list\n`}\u003c/Remark\u003e\n);\n\nexport default ExampleComponent;\n```\n\n#### Using input and events to update\n\n```tsx\nimport React, { useState } from 'react';\nimport { Remark } from 'react-remark';\n\nconst ExampleComponent = () =\u003e {\n  const [markdownSource, setMarkdownSource] = useState('');\n\n  return (\n    \u003c\u003e\n      \u003cinput\n        type=\"text\"\n        onChange={({ currentTarget }) =\u003e setMarkdownSource(currentTarget.value)}\n      /\u003e\n      \u003cRemark\u003e{markdownSource}\u003c/Remark\u003e\n    \u003c/\u003e\n  );\n};\n\nexport default ExampleComponent;\n```\n\n[More examples of usage as component in storybook.](https://remarkjs.github.io/react-remark/?path=/story/remark-component)\n\n## Examples\n\nA set of runnable examples are provided through storybook at \u003chttps://remarkjs.github.io/react-remark\u003e.\nThe source for the story files can be found in [_/stories_](./stories).\n\n## Architecture\n\n```\n                                                             react-remark\n+---------------------------------------------------------------------------------------------------------------------------------------------+\n|                                                                                                                                             |\n|            +----------+        +----------------+        +---------------+       +----------------+       +--------------+                  |\n|            |          |        |                |        |               |       |                |       |              |                  |\n| -markdown-\u003e+  remark  +-mdast-\u003e+ remark plugins +-mdast-\u003e+ remark-rehype +-hast-\u003e+ rehype plugins +-hast-\u003e+ rehype-react +-react elements-\u003e |\n|            |          |        |                |        |               |       |                |       |              |                  |\n|            +----------+        +----------------+        +---------------+       +----------------+       +--------------+                  |\n|                                                                                                                                             |\n+---------------------------------------------------------------------------------------------------------------------------------------------+\n```\n\nrelevant links: [markdown](https://commonmark.org), [remark](https://github.com/remarkjs/remark), [mdast](https://github.com/syntax-tree/mdast), [remark plugins](https://github.com/remarkjs/remark/blob/main/doc/plugins.md), [remark-rehype](https://github.com/remarkjs/remark-rehype), [hast](https://github.com/syntax-tree/hast), [rehype plugins](https://github.com/rehypejs/rehype/blob/main/doc/plugins.md), [rehype-react](https://github.com/rehypejs/rehype-react)\n\n## Options\n\n- `remarkParseOptions` (Object) - configure how Markdown is parsed, same as [`remark-parse` options](https://github.com/remarkjs/remark/tree/main/packages/remark-parse#options)\n- `remarkPlugins` (Array) - [remark plugins](https://github.com/remarkjs/remark/blob/main/doc/plugins.md) or [custom plugins](https://unifiedjs.com/learn/guide/create-a-plugin) to transform markdown content before it is translated to HTML (hast)\n- `remarkToRehypeOptions` (Object) - configure how Markdown (mdast) is translated into HTML (hast), same as [`remark-rehype` options](https://github.com/remarkjs/remark-rehype#api)\n- `rehypePlugins` (Array) - [rehype plugins](https://github.com/rehypejs/rehype/blob/main/doc/plugins.md) or [custom plugins](https://unifiedjs.com/learn/guide/create-a-plugin) to transform HTML (hast) before it is translated to React elements.\n- `rehypeReactOptions` (Object) - configure how HTML (hast) is translated into React elements, same as [`rehype-react` options](https://github.com/rehypejs/rehype-react#options)\n\n### Pass options to hook\n\n```tsx\nimport React, { Fragment } from 'react';\nimport { useRemark } from 'react-remark';\nimport remarkGemoji from 'remark-gemoji';\nimport rehypeSlug from 'rehype-slug';\nimport rehypeAutoLinkHeadings from 'rehype-autolink-headings';\n\n// ...\n\nconst [reactContent, setMarkdownSource] = useRemark({\n  remarkPlugins: [remarkGemoji],\n  remarkToRehypeOptions: { allowDangerousHtml: true },\n  rehypePlugins: [rehypeSlug, rehypeAutoLinkHeadings],\n  rehypeReactOptions: {\n    components: {\n      p: (props) =\u003e \u003cp className=\"custom-paragraph\" {...props} /\u003e,\n    },\n  },\n});\n```\n\n### Pass options to component\n\n```tsx\nimport React, { Fragment } from 'react';\nimport { Remark } from 'react-remark';\nimport remarkGemoji from 'remark-gemoji';\nimport rehypeSlug from 'rehype-slug';\nimport rehypeAutoLinkHeadings from 'rehype-autolink-headings';\n\n// ...\n\n\u003cRemark\n  remarkPlugins={[remarkGemoji]}\n  remarkToRehypeOptions={{ allowDangerousHtml: true }}\n  rehypePlugins={[rehypeSlug, rehypeAutoLinkHeadings]}\n  rehypeReactOptions={{\n    components: {\n      p: (props) =\u003e \u003cp className=\"custom-paragraph\" {...props} /\u003e,\n    },\n  }}\n\u003e\n  {markdownSource}\n\u003c/Remark\u003e;\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremarkjs%2Freact-remark","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fremarkjs%2Freact-remark","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremarkjs%2Freact-remark/lists"}