{"id":18267897,"url":"https://github.com/dance2die/dangerous","last_synced_at":"2026-05-02T17:37:01.225Z","repository":{"id":89529235,"uuid":"165331241","full_name":"dance2die/dangerous","owner":"dance2die","description":"☢⚛ Create dangerous React  components in style","archived":false,"fork":false,"pushed_at":"2019-02-03T02:36:38.000Z","size":399,"stargazers_count":0,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-14T04:06:09.703Z","etag":null,"topics":["dangerouslysetinnerhtml","npm","npm-package","react","react-hook","react-hooks","reactjs","setdangerouslysetinnerhtml","styled-components","tagged-template-literals","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/dangerous","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/dance2die.png","metadata":{"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":"2019-01-12T00:59:02.000Z","updated_at":"2019-01-25T03:42:29.000Z","dependencies_parsed_at":null,"dependency_job_id":"e92887a1-d918-4f00-80b8-400ee6f2d523","html_url":"https://github.com/dance2die/dangerous","commit_stats":{"total_commits":92,"total_committers":1,"mean_commits":92.0,"dds":0.0,"last_synced_commit":"af30e7995067365060092b4b5172121924506ac2"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dance2die/dangerous","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dance2die%2Fdangerous","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dance2die%2Fdangerous/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dance2die%2Fdangerous/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dance2die%2Fdangerous/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dance2die","download_url":"https://codeload.github.com/dance2die/dangerous/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dance2die%2Fdangerous/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259756872,"owners_count":22906678,"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":["dangerouslysetinnerhtml","npm","npm-package","react","react-hook","react-hooks","reactjs","setdangerouslysetinnerhtml","styled-components","tagged-template-literals","typescript"],"created_at":"2024-11-05T11:29:19.617Z","updated_at":"2025-10-26T05:03:18.808Z","avatar_url":"https://github.com/dance2die.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![logo](img/dangerous-logo.jpg)\n\n# ☢ dangerous\n![npm](https://img.shields.io/npm/v/dangerous.svg?style=flat-square)\n![minified size](https://img.shields.io/bundlephobia/min/dangerous.svg?style=flat-square)\n![build](https://img.shields.io/circleci/project/github/dance2die/dangerous/master.svg?style=flat-square)\n\nA utility function to create a dangerous/unsafe React component using tagged literal\ntemplates.\n\nThe syntax is borrowed from [Styled Components](https://www.styled-components.com/).\n\n`dangerous` returns a component, which uses\n[dangerouslySetInnerHTML](https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml)\ninternally to convert your dangerous input to set literal to DOM's innerHTML\nvalue.\n\n# ⚠️ Requirement\n\nMinimum required version of React is v16.3.0 because  `dangerous` uses [React.forwardRef](https://reactjs.org/docs/react-api.html#reactforwardref), which was [introduced in v16.3.0](https://reactjs.org/blog/2018/03/29/react-v-16-3.html#forwardref-api).\n\n## Installation\n\n```sh\n$ npm i dangerous\n# or\n$ yarn add dangerous\n```\n\n## ✍ Usage\n\n### 👶 Basic Usage\n\nYou can pass raw HTML to `dangerous` using tagged template literal.\n\n```js\nconst DangerousComponent = dangerous.div`💖 \u0026amp; 🕊`;\n// or\nconst DangerousComponent = dangerous('div')`💖 \u0026amp; 🕊`\n```\n\nYou can Subtitute `div` with any valid [DOM elements](https://github.com/dance2die/dangerous/blob/master/src/domElements.ts) or a custom React component.  \n\n```js\nconst DangerousComponent = dangerous.span`💖 \u0026amp; 🕊`\nconst DangerousComponent = dangerous.p`💖 \u0026amp; 🕊`\nconst DangerousComponent = dangerous.section`💖 \u0026amp; 🕊`\n// and\nconst DangerousComponent = dangerous(CustomComponent)`💖 \u0026amp; 🕊`\n```\n\n#### Render Result\n\nDangerous component will set `\u0026emp;` directly so the rendered result will show\n```html\n💖 \u0026 🕊\n```\n\nwhile React will render it as\n```html\n💖 \u0026amp; 🕊\n```\nas shown below.\n\n![basic-usage-render-result](img/basic-render.png)\n\n### 🐱‍👤 Advanced Usage\n\n`dangerous` returns a React component, to which you can pass props, which you can access within tagged template literal.\n\n```js\nconst DangerousComponent = dangerous.div`\n  \u003ch1\u003eWho am I?\u003c/h1\u003e\n  \u003cp\u003eLast Name is \"${props =\u003e props.lastName}\"\u003c/p\u003e\n  \u003cp\u003eFirst Name is \"${props =\u003e props.firstName}\"\u003c/p\u003e\n  \u003ca href=\"javascript:alert('${({ firstName, lastName }) =\u003e\n    `Hi ${firstName} ${lastName}`}');\"\u003eShow Alert\u003c/a\u003e`;\n\nfunction App() {\n  return \u003cDangerousComponent firstName=\"Sung\" lastName=\"Kim\" /\u003e;\n}\n```\n\nIn the code above, `\u003cDangerousComponent /\u003e` is passed following props in `App`.\n1. `firstName=\"Sung\"`\n1. `lastName=\"Kim\"`\n\nYou can access the props in the tagged literal using `${props =\u003e props.properyName}`.  \n_This was taken directly from [Styled Component syntax](https://www.styled-components.com/docs/basics#passed-props)._\n\nAnd you can destructure props and combine it to compose any string you want.\n\n```js\nconst DangerousComponent = dangerous.div`\n  //... omitted for brevity\n  \u003ca href=\"javascript:alert('${({ firstName, lastName }) =\u003e `Hi ${firstName} ${lastName}`}');\"\u003eShow Alert\u003c/a\u003e`;\n```\n\n### ⤵ Return object\n\n`dangerous` returns a React component and behaves like a HoC ([High-order Component](https://reactjs.org/docs/higher-order-components.html)).  \n\nIf a custom component is passed to `dangerous`, then all static properties will be hoisted down to the wrapped component.\n\n\n# 👨‍💻 Example\n\nThe example below shows how to use `dangerous` with a custom `Block` components with static properties and Styled Components, `StyledDangerous` \u0026 `StyledBlock`.\n\nIt also demo's wrapping `StyledBlock` (a Styled Component component 😅) with `dangerous` as `DangerousStyled`.\n\n[![Edit Dangerous Demo - Styled Components](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/q7vn2p20rq)\n\n```jsx\nimport React from \"react\";\nimport ReactDOM from \"react-dom\";\n\nimport styled from \"styled-components\";\nimport dangerous from \"dangerous\";\n\nimport \"./styles.css\";\n\nclass Block extends React.Component {\n  // To check if static fields are hoised correctly\n  static count = 10;\n  static increaseCount = () =\u003e console.log(++Block.count);\n  static decreaseCount = () =\u003e console.log(--Block.count);\n\n  render() {\n    return \u003cdiv {...this.props} /\u003e;\n  }\n}\n\nconst Dangerous = dangerous.div`\n  \u003ch1\u003eWho am I?\u003c/h1\u003e\n  \u003cp\u003eLast Name is \"${props =\u003e props.lastName}\"\u003c/p\u003e\n  \u003cp\u003eFirst Name is \"${props =\u003e props.firstName}\"\u003c/p\u003e\n  \u003ca href=\"javascript:alert('${({ firstName, lastName }) =\u003e\n    `Hi ${firstName} ${lastName}`}');\"\u003eShow Alert\u003c/a\u003e`;\n\nconst StyledDangerous = styled(Dangerous)`\n  background-color: papayawhip;\n  padding: 1.5em 0;\n`;\n\nconst StyledBlock = styled(Block)`\n  background-color: hotpink;\n  padding: 1.5em 0;\n`;\n\nconst DangerousStyled = dangerous(StyledBlock)`\n  \u003ch1\u003eAlter Ego\u003c/h1\u003e\n  \u003cp\u003eClick link below to find out who my alter ego is\u003c/p\u003e\n  \u003ca href=\"javascript:alert('${props =\u003e props.name}');\"\u003eShow Aleter Ego Name\u003c/a\u003e\n`;\n\nfunction App() {\n  return (\n    \u003cdiv className=\"App\"\u003e\n      \u003csection\u003e\n        \u003cStyledDangerous firstName=\"Sung\" lastName=\"Kim\" /\u003e\n        \u003cDangerousStyled name=\"dance2die\" /\u003e\n      \u003c/section\u003e\n    \u003c/div\u003e\n  );\n}\n\nconst rootElement = document.getElementById(\"root\");\nReactDOM.render(\u003cApp /\u003e, rootElement);\n```\n\n### 🥊 Demo in action\n\n![demo](img/demo.gif)\n\n\n# 💪 To Dos\n1. Create a GitHub project for version 1.\n    1. Add TypeScript types\n    1. Add TypeScript definition files to distribution\n    1. Add tests\n1. Update Logo to look as stylish as that of Styled Components's. 😄\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdance2die%2Fdangerous","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdance2die%2Fdangerous","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdance2die%2Fdangerous/lists"}