html-react-parser vs react-html-parser vs dangerously-set-html-content vs react-render-html
HTML Parsing and Rendering in React Comparison
1 Year
html-react-parserreact-html-parserdangerously-set-html-contentreact-render-htmlSimilar Packages:
What's HTML Parsing and Rendering in React?

HTML parsing and rendering libraries for React are tools that allow developers to safely and efficiently render HTML content within React components. These libraries provide functionality to parse HTML strings, handle potentially dangerous content, and convert it into React elements while mitigating security risks such as Cross-Site Scripting (XSS) attacks. They are essential for applications that need to display dynamic HTML content, user-generated content, or content from external sources while maintaining a secure and performant rendering process. Each library offers different features, APIs, and levels of security, making it important for developers to choose one that aligns with their project requirements and security considerations.

Package Weekly Downloads Trend
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
html-react-parser1,881,1752,315470 kB114 days agoMIT
react-html-parser239,618796-578 years agoMIT
dangerously-set-html-content134,046625.73 kB22 years agoMIT
react-render-html19,359216-208 years agoMIT
Feature Comparison: html-react-parser vs react-html-parser vs dangerously-set-html-content vs react-render-html

Security Features

  • html-react-parser:

    html-react-parser does not sanitize HTML by default, which means it is up to the developer to ensure that the HTML content being parsed is safe. However, it allows for custom transformations and can be extended to include sanitization if needed, giving developers flexibility but requiring them to handle security concerns.

  • react-html-parser:

    react-html-parser does not include built-in sanitization, so it is important to ensure that the HTML content is safe before using this library. Developers should sanitize the HTML content themselves to prevent XSS attacks, making it crucial to implement security measures when using this library.

  • dangerously-set-html-content:

    dangerously-set-html-content provides built-in XSS protection by sanitizing HTML content before rendering. It uses the dompurify library to clean the HTML, ensuring that any potentially harmful scripts or tags are removed, making it a secure choice for rendering user-generated content.

  • react-render-html:

    react-render-html does not provide built-in sanitization of HTML content. Developers are responsible for ensuring that the HTML being rendered is safe to prevent XSS vulnerabilities. It is recommended to sanitize the HTML content before passing it to this library for rendering.

Customization and Flexibility

  • html-react-parser:

    html-react-parser is highly customizable, allowing developers to define how specific HTML tags are rendered through custom transformation functions. This flexibility makes it suitable for projects that require more control over the rendering process and the ability to handle different HTML elements in unique ways.

  • react-html-parser:

    react-html-parser provides basic customization by allowing developers to specify how certain HTML tags are rendered by passing in custom components. However, it is not as flexible as some other libraries, making it more suitable for simple use cases where only minimal customization is needed.

  • dangerously-set-html-content:

    dangerously-set-html-content offers limited customization options, as it is primarily focused on securely rendering HTML content. It does not provide extensive APIs for modifying the rendering process, making it a straightforward solution with minimal configuration.

  • react-render-html:

    react-render-html offers limited customization capabilities, focusing primarily on rendering HTML content as-is. It does not provide APIs for customizing the rendering of specific tags or elements, which may limit its use in projects that require more granular control over the rendering process.

Performance

  • html-react-parser:

    html-react-parser is lightweight and optimized for performance, especially when compared to other HTML parsing libraries. Its ability to parse and render HTML content efficiently makes it a good choice for applications that require fast rendering without a lot of resource consumption.

  • react-html-parser:

    react-html-parser is a lightweight library that performs well when converting HTML strings to React elements. However, its performance may be affected by the complexity of the HTML being parsed, especially if it contains a large number of nested elements.

  • dangerously-set-html-content:

    dangerously-set-html-content is designed for performance, with minimal overhead during the rendering process. The use of dompurify for sanitization is efficient and does not significantly impact performance, making it suitable for applications that need to render HTML content quickly and securely.

  • react-render-html:

    react-render-html is a lightweight library that renders HTML content quickly with minimal performance overhead. Its simplicity and focus on rendering make it efficient for applications that need to display HTML content without significant resource usage.

Ease of Use: Code Examples

  • html-react-parser:

    Example of using html-react-parser

    import React from 'react';
    import parse from 'html-react-parser';
    
    const HtmlParserComponent = ({ htmlString }) => {
      return <div>{parse(htmlString)}</div>;
    };
    
    export default HtmlParserComponent;
    
  • react-html-parser:

    Example of using react-html-parser

    import React from 'react';
    import ReactHtmlParser from 'react-html-parser';
    
    const HtmlParserComponent = ({ htmlString }) => {
      return <div>{ReactHtmlParser(htmlString)}</div>;
    };
    
    export default HtmlParserComponent;
    
  • dangerously-set-html-content:

    Example of using dangerously-set-html-content

    import React from 'react';
    import { setHtml } from 'dangerously-set-html-content';
    
    const SafeHtmlComponent = ({ htmlContent }) => {
      return <div>{setHtml(htmlContent)}</div>;
    };
    
    export default SafeHtmlComponent;
    
  • react-render-html:

    Example of using react-render-html

    import React from 'react';
    import renderHTML from 'react-render-html';
    
    const HtmlRendererComponent = ({ htmlString }) => {
      return <div>{renderHTML(htmlString)}</div>;
    };
    
    export default HtmlRendererComponent;
    
How to Choose: html-react-parser vs react-html-parser vs dangerously-set-html-content vs react-render-html
  • html-react-parser:

    Choose html-react-parser if you need a lightweight and flexible parser that allows for custom transformations of HTML elements during rendering. It is suitable for projects that require more control over how HTML is parsed and rendered, with support for React fragments and components.

  • react-html-parser:

    Choose react-html-parser if you want a straightforward library that converts HTML strings into React elements with minimal configuration. It is best for projects that need a simple and easy-to-use solution for rendering HTML without complex features.

  • dangerously-set-html-content:

    Choose dangerously-set-html-content if you need a simple and secure way to render HTML content with built-in XSS protection. It is ideal for projects that require a straightforward solution without the need for extensive customization.

  • react-render-html:

    Choose react-render-html if you need a lightweight library that focuses on rendering HTML content safely. It is ideal for projects that prioritize simplicity and performance while ensuring that the rendered HTML is safe from XSS attacks.

README for html-react-parser

html-react-parser

NPM

NPM version Bundlephobia minified + gzip build codecov NPM downloads Discord

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

HTMLReactParser(string[, options])

The parser converts an HTML string to one or more React elements.

To replace an element with another element, check out the replace option.

Example

import parse from 'html-react-parser';

parse('<p>Hello, World!</p>'); // React.createElement('p', {}, 'Hello, World!')

Replit | JSFiddle | StackBlitz | TypeScript | Examples

Table of Contents

Install

NPM:

npm install html-react-parser --save

Yarn:

yarn add html-react-parser

CDN:

<!-- HTMLReactParser depends on React -->
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script src="https://unpkg.com/html-react-parser@latest/dist/html-react-parser.min.js"></script>
<script>
  window.HTMLReactParser(/* string */);
</script>

Usage

Import ES module:

import parse from 'html-react-parser';

Or require CommonJS module:

const parse = require('html-react-parser').default;

Parse single element:

parse('<h1>single</h1>');

Parse multiple elements:

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

Make sure to render parsed adjacent elements under a parent element:

<ul>
  {parse(`
    <li>Item 1</li>
    <li>Item 2</li>
  `)}
</ul>

Parse nested elements:

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

Parse element with attributes:

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

replace

The replace option allows you to replace an element with another element.

The replace callback's first argument is domhandler's node:

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

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

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

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

The second argument is the index:

parse('<br>', {
  replace(domNode, index) {
    console.assert(typeof index === 'number');
  },
});

[!NOTE] The index will restart at 0 when traversing the node's children so don't rely on index being a unique key. See #1259.

replace with TypeScript

You need to check that domNode is an instance of domhandler's Element:

import { HTMLReactParserOptions, Element } from 'html-react-parser';

const options: HTMLReactParserOptions = {
  replace(domNode) {
    if (domNode instanceof Element && domNode.attribs) {
      // ...
    }
  },
};

Or use a type assertion:

import { HTMLReactParserOptions, Element } from 'html-react-parser';

const options: HTMLReactParserOptions = {
  replace(domNode) {
    if ((domNode as Element).attribs) {
      // ...
    }
  },
};

If you're having issues, take a look at our Create React App example.

replace element and children

Replace the element and its children (see demo):

import parse, { domToReact } from 'html-react-parser';

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

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

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

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

parse(html, options);
HTML output

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

replace element attributes

Convert DOM attributes to React props with attributesToProps:

import parse, { attributesToProps } from 'html-react-parser';

const html = `
  <main class="prettify" style="background: #fff; text-align: center;" />
`;

const options = {
  replace(domNode) {
    if (domNode.attribs && domNode.name === 'main') {
      const props = attributesToProps(domNode.attribs);
      return <div {...props} />;
    }
  },
};

parse(html, options);
HTML output

<div class="prettify" style="background:#fff;text-align:center"></div>

replace and remove element

Exclude an element from rendering by replacing it with <React.Fragment>:

parse('<p><br id="remove"></p>', {
  replace: ({ attribs }) => attribs?.id === 'remove' && <></>,
});
HTML output

<p></p>

transform

The transform option allows you to transform each element individually after it's parsed.

The transform callback's first argument is the React element:

parse('<br>', {
  transform(reactNode, domNode, index) {
    // this will wrap every element in a div
    return <div>{reactNode}</div>;
  },
});

library

The library option specifies the UI library. The default library is React.

To use Preact:

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

Or a custom library:

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

htmlparser2

[!WARNING] htmlparser2 options don't work on the client-side (browser); they only work on the server-side (Node.js). By overriding the options, it can break universal rendering.

Default htmlparser2 options can be overridden in >=0.12.0.

To enable xmlMode:

parse('<p /><p />', {
  htmlparser2: {
    xmlMode: true,
  },
});

trim

By default, whitespace is preserved:

parse('<br>\n'); // [React.createElement('br'), '\n']

But certain elements like <table> will strip out invalid whitespace:

parse('<table>\n</table>'); // React.createElement('table')

To remove whitespace, enable the trim option:

parse('<br>\n', { trim: true }); // React.createElement('br')

However, intentional whitespace may be stripped out:

parse('<p> </p>', { trim: true }); // React.createElement('p')

Migration

v5

Migrated to TypeScript. CommonJS imports require the .default key:

const parse = require('html-react-parser').default;

If you're getting the error:

Argument of type 'ChildNode[]' is not assignable to parameter of type 'DOMNode[]'.

Then use type assertion:

domToReact(domNode.children as DOMNode[], options);

See #1126.

v4

htmlparser2 has been upgraded to v9.

v3

domhandler has been upgraded to v5 so some parser options like normalizeWhitespace have been removed.

Also, it's recommended to upgrade to the latest version of TypeScript.

v2

Since v2.0.0, Internet Explorer (IE) is no longer supported.

v1

TypeScript projects will need to update the types in v1.0.0.

For the replace option, you may need to do the following:

import { Element } from 'domhandler/lib/node';

parse('<br class="remove">', {
  replace(domNode) {
    if (domNode instanceof Element && domNode.attribs.class === 'remove') {
      return <></>;
    }
  },
});

Since v1.1.1, Internet Explorer 9 (IE9) is no longer supported.

FAQ

Is this XSS safe?

No, this library is not XSS (cross-site scripting) safe. See #94.

Does invalid HTML get sanitized?

No, this library does not sanitize HTML. See #124, #125, and #141.

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.

Attributes aren't getting called

The reason why your HTML attributes aren't getting called is because inline event handlers (e.g., onclick) are parsed as a string rather than a function. See #73.

Parser throws an error

If the parser throws an error, check if your arguments are valid. See "Does invalid HTML get sanitized?".

Is SSR supported?

Yes, server-side rendering on Node.js is supported by this library. See demo.

Elements aren't nested correctly

If your elements are nested incorrectly, check to make sure your HTML markup is valid. The HTML to DOM parsing will be affected if you're using self-closing syntax (/>) on non-void elements:

parse('<div /><div />'); // returns single element instead of array of elements

See #158.

Don't change case of tags

Tags are lowercased by default. To prevent that from happening, pass the htmlparser2 option:

const options = {
  htmlparser2: {
    lowerCaseTags: false,
  },
};
parse('<CustomElement>', options); // React.createElement('CustomElement')

[!WARNING] By preserving case-sensitivity of the tags, you may get rendering warnings like:

Warning: <CustomElement> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.

See #62 and example.

TS Error: Property 'attribs' does not exist on type 'DOMNode'

The TypeScript error occurs because DOMNode needs to be an instance of domhandler's Element. See migration or #199.

Can I enable trim for certain elements?

Yes, you can enable or disable trim for certain elements using the replace option. See #205.

Webpack build warnings

If you see the Webpack build warning:

export 'default' (imported as 'parse') was not found in 'html-react-parser'

Then update your Webpack config to:

// webpack.config.js
module.exports = {
  // ...
  resolve: {
    mainFields: ['browser', 'main', 'module'],
  },
};

See #238 and #213.

TypeScript error

If you see the TypeScript error:

node_modules/htmlparser2/lib/index.d.ts:2:23 - error TS1005: ',' expected.

2 export { Parser, type ParserOptions };
                        ~~~~~~~~~~~~~

Then upgrade to the latest version of typescript. See #748.

Performance

Run benchmark:

npm run benchmark

Output of benchmark run on MacBook Pro 2021:

html-to-react - Single x 1,018,239 ops/sec ±0.43% (94 runs sampled)
html-to-react - Multiple x 380,037 ops/sec ±0.61% (97 runs sampled)
html-to-react - Complex x 35,091 ops/sec ±0.50% (96 runs sampled)

Run Size Limit:

npx size-limit

Contributors

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]

Individuals

Financial Contributors - Individuals

Organizations

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

Support

License

MIT