{"id":13469644,"url":"https://github.com/pveyes/htmr","last_synced_at":"2025-05-15T15:07:11.929Z","repository":{"id":38272368,"uuid":"100122112","full_name":"pveyes/htmr","owner":"pveyes","description":"Simple and lightweight (\u003c 2kB) HTML string to React element conversion library","archived":false,"fork":false,"pushed_at":"2024-07-12T00:10:07.000Z","size":1228,"stargazers_count":531,"open_issues_count":6,"forks_count":32,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-12T07:43:31.147Z","etag":null,"topics":["converter","html","jsx","lightweight","oss","parser","react","react-native","simple"],"latest_commit_sha":null,"homepage":"","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/pveyes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":"pveyes"}},"created_at":"2017-08-12T15:49:12.000Z","updated_at":"2025-04-28T13:18:13.000Z","dependencies_parsed_at":"2024-11-28T07:18:28.792Z","dependency_job_id":null,"html_url":"https://github.com/pveyes/htmr","commit_stats":{"total_commits":186,"total_committers":10,"mean_commits":18.6,"dds":0.3978494623655914,"last_synced_commit":"c04888135e960b2fdc2f557ee328b066e88db25e"},"previous_names":[],"tags_count":37,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pveyes%2Fhtmr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pveyes%2Fhtmr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pveyes%2Fhtmr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pveyes%2Fhtmr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pveyes","download_url":"https://codeload.github.com/pveyes/htmr/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254364270,"owners_count":22058878,"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":["converter","html","jsx","lightweight","oss","parser","react","react-native","simple"],"created_at":"2024-07-31T15:01:48.311Z","updated_at":"2025-05-15T15:07:06.914Z","avatar_url":"https://github.com/pveyes.png","language":"TypeScript","readme":"# htmr [![Actions Status](https://github.com/pveyes/htmr/workflows/test/badge.svg)](https://github.com/pveyes/htmr/actions) [![bundle size](http://img.badgesize.io/https://unpkg.com/htmr/lib/htmr.browser.js?compression=gzip)](https://unpkg.com/htmr/lib/htmr.browser.js)\n\n\u003e Simple and lightweight (\u003c 2kB) HTML string to react element conversion library\n\n## Install\n\n```sh\n$ yarn add htmr\n\n# or\n\n$ npm install htmr --save\n```\n\n## Usage\n\nUse the default export, and pass HTML string.\n\n```js\nimport React from 'react';\nimport htmr from 'htmr';\n\nfunction HTMLComponent() {\n  return htmr('\u003cp\u003eNo more dangerouslySetInnerHTML\u003c/p\u003e');\n}\n```\n\nThe API also accepts second argument `options` containing few optional fields. Below are their default values:\n\n```js\nconst options = {\n  transform: {},\n  preserveAttributes: [],\n  dangerouslySetChildren: ['style'],\n};\nhtmr(html, options);\n```\n\n### transform\n\ntransform accepts key value pairs, that will be used to transforms node (key) to custom component (value). You can use it to render specific tag name with custom component. For example: component with\npredefined styles like\n[styled-components](https://github.com/styled-components/styled-components).\n\n```js\nimport React from 'react';\nimport htmr from 'htmr';\nimport styled from 'styled-components';\n\nconst Paragraph = styled.p`\n  font-family: Helvetica, Arial, sans-serif;\n  line-height: 1.5;\n`;\n\nconst transform = {\n  p: Paragraph,\n  // you can also pass string for native DOM node\n  a: 'span',\n};\n\nfunction TransformedHTMLComponent() {\n  // will return \u003cParagraph\u003e\u003cspan\u003e{'Custom component'}\u003c/span\u003e\u003c/Paragraph\u003e\n  return htmr('\u003cp\u003e\u003ca\u003eCustom component\u003c/a\u003e\u003c/p\u003e', { transform });\n}\n```\n\nYou can also provide default transform using underscore `_` as property name.\n\nThis can be useful if you want to do string preprocessing (like removing all whitespace), or rendering HTML as native view in [react-native](https://github.com/facebook/react-native):\n\n```js\nimport React from 'react';\nimport { Text, View } from 'react-native';\n\nconst transform = {\n  div: View,\n  _: (node, props, children) =\u003e {\n    // react-native can't render string without \u003cText\u003e component\n    // we can test text node by checking component props, text node won't have them\n    if (typeof props === 'undefined') {\n      // use `key` because it's possible that \u003cText\u003e is rendered\n      // inside array as sibling\n      return \u003cText key={node}\u003e{node}\u003c/Text\u003e;\n    }\n\n    // render unknown tag using \u003cView\u003e\n    // ideally you also filter valid props to \u003cView /\u003e\n    return \u003cView {...props}\u003e{children}\u003c/View\u003e;\n  },\n};\n\nfunction NativeHTMLRenderer(props) {\n  return htmr(props.html, { transform });\n}\n```\n\n### preserveAttributes\n\nBy default `htmr` will convert HTML attributes to camelCase because that's what React uses. You can override this behavior by passing `preserveAttributes` options. Specify array of string / regular expression to test which attributes you want to preserve.\n\nFor example you want to make sure `ng-if`, `v-if` and `v-for` to be rendered as is\n\n```js\nhtmr(html, { preserveAttributes: ['ng-if', new RegExp('v-')] });\n```\n\n### dangerouslySetChildren\n\nBy default `htmr` will only render children of `style` tag inside `dangerouslySetInnerHTML` due to security reason. You can override this behavior by passing array of HTML tags if you want the children of the tag to be rendered dangerously.\n\n```js\nhtmr(html, { dangerouslySetChildren: ['code', 'style'] });\n```\n\n**Note** that if you still want `style` tag to be rendered using `dangerouslySetInnerHTML`, you still need to include it in the array.\n\n## Multiple children\n\nYou can also convert HTML string which contains multiple elements. This returns\nan array, so make sure to wrap the output inside other component such as div, or\nuse React 16.\n\n```js\nimport React from 'react';\nimport htmr from 'htmr';\n\nconst html = `\n  \u003ch1\u003eThis string\u003c/h1\u003e\n  \u003cp\u003eContains multiple html tags\u003c/p\u003e\n  \u003cp\u003eas sibling\u003c/p\u003e\n`;\n\nfunction ComponentWithSibling() {\n  // if using react 16, simply use the return value because\n  // v16 can render array\n  return htmr(html);\n  // if using react 15 and below, wrap in another component\n  return \u003cdiv\u003e{htmr(html)}\u003c/div\u003e;\n}\n```\n\n## Use Cases\n\nThis library was initially built to provides easy component mapping between HTML\nstring and React component. It's mainly used to render custom\ncomponent from HTML string returned from an API. This library **prioritize\nfile size and simple API** over full HTML conversion coverage and other features\nlike JSX parsing or flexible node traversal.\n\nThat's why I've decided to not implement some features (see **Trade Off**\nsection below). If you feel like you need more features that's not possible\nusing this library, you can check out some related projects below.\n\n## Trade Off\n\n- Inline event attributes (`onclick=\"\"` etc) are not supported due to unnecessary complexity\n- htmr use native browser HTML parser when run in browser instead of using custom parser. Due to how browser HTML parser works, you can get weird result if you supply \"invalid\" html, for example `div` inside `p` element like `\u003cp\u003e\u003cdiv\u003etext\u003c/div\u003e\u003c/p\u003e`\n- Script tag is not rendered using `dangerouslySetInnerHTML` by default due to security. You can opt in by using [`dangerouslySetChildren`](#dangerouslysetchildren)\n- Style tag renders it children using `dangerouslySetInnerHTML` by default. You can also reverse this behavior using same method.\n\n## Related projects\n\nHTML to react element:\n\n- [html-to-react](https://github.com/aknuds1/html-to-react)\n- [react-html-parser](https://github.com/wrakky/react-html-parser)\n- [html-react-parser](https://github.com/remarkablemark/html-react-parser)\n- [react-render-html](https://github.com/noraesae/react-render-html)\n\nHTML (page) to react component (file/string):\n\n- [html-to-react-components](https://github.com/roman01la/html-to-react-components)\n- [react-magic](https://github.com/reactjs/react-magic)\n\n## License\n\nMIT\n","funding_links":["https://github.com/sponsors/pveyes"],"categories":["TypeScript","H","Open Source Project"],"sub_categories":["Utility"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpveyes%2Fhtmr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpveyes%2Fhtmr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpveyes%2Fhtmr/lists"}