Skip to content
📝 HTML to React parser.
JavaScript TypeScript
Branch: master
Clone or download
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github chore(github): tidy comments in `` Sep 13, 2019
benchmark refactor(benchmark): move benchmark from test to its own directory Oct 11, 2018
examples chore(examples): add example app bootstrapped by Create React App Jul 10, 2019
lib refactor(dom-to-react): change how library option works Nov 7, 2019
test test(types): move TypeScript tests from `lint` to `test` directory Nov 9, 2019
.commitlintrc.json chore(lint): ensure commit type is never empty Mar 30, 2018
.eslintrc chore: set `parserOptions.sourceType` to "module" in `.eslintrc` Jun 23, 2019
.gitignore chore(git): update `.gitignore` and ignore `.nyc_output` directory Jun 23, 2019
.huskyrc chore(git): update `.huskyrc` to run test coverage in pre-commit Jun 23, 2019
.lintstagedrc chore(lint): update `.lintstagedrc` to prettify other extensions Jun 23, 2019
.npmrc chore(npm): create .npmrc and add it to .npmignore Nov 29, 2017
.prettierrc chore(lint): create .prettierrc add prettier plugin to .eslintrc Jun 8, 2018
.travis.yml ci(travis): fix script `npm run lint:dts` Nov 9, 2019 chore(release): 0.10.0 Nov 9, 2019 chore: add `` Oct 19, 2019 docs: move test, lint, release from to Nov 9, 2019
LICENSE Update MIT license header Sep 26, 2016 docs(readme): refactor html links to markdown links Nov 9, 2019
index.d.ts refactor(dom-to-react): change how library option works Nov 7, 2019
index.js docs(index): improve JSDoc in `index.d.ts` and `index.js` Jul 9, 2019
package.json chore(release): 0.10.0 Nov 9, 2019
rollup.config.js build: replace `webpack` with `rollup` in order to optimize bundle Jul 9, 2019
tsconfig.json test(types): move TypeScript tests from `lint` to `test` directory Nov 9, 2019
tslint.json refactor(types): moved to root Apr 2, 2019



NPM version Build Status Coverage Status Dependency status NPM downloads Financial Contributors on Open Collective

HTML to React parser that works on both the server (Node.js) and the client (browser):

HTMLReactParser(string[, options])

It converts an HTML string to one or more React elements. There's also an option to replace an element with your own.


var parse = require('html-react-parser');
parse('<div>text</div>'); // equivalent to `React.createElement('div', {}, 'text')`

CodeSandbox | JSFiddle | | Examples



$ npm install html-react-parser --save


$ yarn add html-react-parser


<!-- HTMLReactParser depends on React -->
<script src=""></script>
<script src=""></script>
  window.HTMLReactParser(/* string */);


Import the module:

// CommonJS
const parse = require('html-react-parser');

// ES Modules
import parse from 'html-react-parser';

Parse single element:


Parse multiple elements:

parse('<li>Item 1</li><li>Item 2</li>');

Since adjacent elements are parsed as an array, make sure to render them under a parent node:

    <li>Item 1</li>
    <li>Item 2</li>

Parse nested elements:

parse('<body><p>Lorem ipsum</p></body>');

Parse element with attributes:

  '<hr id="foo" class="bar" data-attr="baz" custom="qux" style="top:42px;">'



The replace callback allows you to swap an element with another React element.

The first argument is an object with the same output as htmlparser2's domhandler:

parse('<br>', {
  replace: function(domNode) {
    console.dir(domNode, { depth: null });

Console output:

{ type: 'tag',
  name: 'br',
  attribs: {},
  children: [],
  next: null,
  prev: null,
  parent: null }

The element is replaced only if a valid React element is returned:

parse('<p id="replace">text</p>', {
  replace: domNode => {
    if (domNode.attribs && === 'replace') {
      return React.createElement('span', {}, 'replaced');

Here's an example that modifies an element but keeps the children:

import React from 'react';
import { renderToStaticMarkup } from 'react-dom/server';
import parse, { domToReact } from 'html-react-parser';

const html = `
  <p id="main">
    <span class="prettify">
      keep me and make me pretty!

const options = {
  replace: ({ attribs, children }) => {
    if (!attribs) return;

    if ( === 'main') {
      return <h1 style={{ fontSize: 42 }}>{domToReact(children, options)}</h1>;

    if (attribs.class === 'prettify') {
      return (
        <span style={{ color: 'hotpink' }}>
          {domToReact(children, options)}

console.log(renderToStaticMarkup(parse(html, options)));


<h1 style="font-size:42px">
  <span style="color:hotpink">
    keep me and make me pretty!

Here's an example that excludes an element:

parse('<p><br id="remove"></p>', {
  replace: ({ attribs }) => attribs && === 'remove' && <Fragment />


The library option allows you to specify which component library is used to create elements. React is used by default if this option is not specified.

Here's an example showing how to use Preact:

parse('<br>', {
  library: require('preact')

Or, using a custom library:

parse('<br>', {
  library: {
    cloneElement: () => {
      /* ... */
    createElement: () => {
      /* ... */
    isValidElement: () => {
      /* ... */


Is this library XSS safe?

No, this library is not XSS (Cross-Site Scripting) safe. See #94.

Does this library sanitize invalid HTML?

No, this library does not perform HTML sanitization. See #124.

Are <script> tags parsed?

Although <script> tags and their contents are rendered on the server-side, they're not evaluated on the client-side. See #98.

Why aren't my HTML attributes getting called?

This is because inline event handlers (e.g., onclick) are parsed as a string instead of a function. See #73.


$ npm run test:benchmark

Here's an example output of the benchmarks run on a MacBook Pro 2017:

html-to-react - Single x 415,186 ops/sec ±0.92% (85 runs sampled)
html-to-react - Multiple x 139,780 ops/sec ±2.32% (87 runs sampled)
html-to-react - Complex x 8,118 ops/sec ±2.99% (82 runs sampled)


Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Code Contributors

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]


Financial Contributors - Individuals


Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

Financial Contributors - Organization 0 Financial Contributors - Organization 1 Financial Contributors - Organization 2 Financial Contributors - Organization 3 Financial Contributors - Organization 4 Financial Contributors - Organization 5 Financial Contributors - Organization 6 Financial Contributors - Organization 7 Financial Contributors - Organization 8 Financial Contributors - Organization 9




You can’t perform that action at this time.