Skip to content
/React Native HTML Renderer
Developer ToolsiOS · Android

React Native HTML Renderer

Native HTML Rendering Library (npm)

Open Source
Users
0+
Screens
TypeScriptReact Nativehtmlparser2css-to-react-nativeJestTurboreporeact-native-builder-bobyarn@4

About the Project

@neeleshyadav/react-native-html-renderer is a modern, TypeScript-first replacement for the abandoned react-native-render-html. It parses HTML strings and renders them as 100% native React Native components — no WebView, no iframe, no hidden DOM. The library is actively maintained, lightweight, and ships with sensible defaults around security, accessibility, and theming.

The architecture is modular: a parser built on htmlparser2 with LRU caching, a sanitiser layer that strips dangerous tags and URL schemes by default, a styles module that handles CSS → StyleSheet conversion plus cascade ordering, and a renderer layer with per-node error boundaries so a single failing tag never collapses the tree. A context provider propagates shared config (contentWidth, styles, colorScheme) to custom renderers and hooks.

Security is enabled by default: script, iframe, object, embed, form, svg, and math tags are stripped; any on* event-handler attribute is blocked; javascript:, vbscript:, and data:text/html URLs are rejected; URL attributes are normalised to strip control-character bypasses; and prototype-pollution attempts (__proto__, constructor, prototype) are rejected at the attribute level. A max DOM depth of 100 prevents stack-overflow attacks from deeply nested input.

Dark mode is automatic via useColorScheme() with per-tag overrides available through darkModeStyles, and font scaling respects system accessibility settings with an optional maxFontSizeMultiplier cap. ARIA attributes map into React Native's accessibility props — aria-label, aria-hidden, aria-role, aria-disabled/checked/expanded/busy/selected — so screen readers work out of the box.

Performance is driven by two LRU caches: 50 parsed DOM trees and 200 image dimensions (keyed to avoid cache poisoning across allowDangerousHtml / ignoredTags permutations). Custom renderers receive a full context (node, children, merged style, attributes, passProps, renderChildren, contentWidth) so consumers can override any tag. The project ships with ~118 Jest tests across 7 suites covering parsing, sanitising, caching, styles, accessibility, and rendering.

Key Highlights

Renders HTML into 100% native React Native views — no WebView
TypeScript-first with strict mode and full type exports
XSS sanitisation on by default — dangerous tags, URL schemes, and handlers stripped
Automatic dark mode via useColorScheme with per-tag overrides
Full accessibility — ARIA → accessibility props mapping for screen readers
LRU caching for parsed DOM (50) and image dimensions (200)
Custom renderer API lets consumers override any HTML tag
~118 Jest tests across 7 suites covering every module

Technical Breakdown

Feature areas & implementation details

Rendering Engine
htmlparser2-powered parser handles malformed HTML gracefully
CSS → React Native StyleSheet via css-to-react-native
Style cascade: default → tagsStyles → classesStyles → idsStyles → inline
Max DOM depth of 100 prevents stack-overflow from nested input
Custom renderers receive node, children, style, attrs, passProps, renderChildren, contentWidth
30+ supported tags: headings, lists, tables, links, images, forms (read-only), code
Security by Default
Strips script, iframe, object, embed, form, svg, math, template, and more
Blocks any attribute starting with 'on' (onclick, onerror, onload, …)
Rejects javascript:, vbscript:, and data:text/html URL schemes
Allows only http, https, mailto, tel, sms, geo, and data:image/ URIs
Blocks __proto__ / constructor / prototype keys to prevent prototype pollution
Normalises URLs to strip control-character and whitespace bypass attempts
Theming & Accessibility
useColorScheme() drives automatic dark mode with darkModeStyles overrides
allowFontScaling + maxFontSizeMultiplier respect system accessibility
ARIA mapping: aria-label / aria-hidden / aria-role / aria-disabled / aria-checked / aria-expanded / aria-busy
Links get accessibilityRole='link' with accessibilityHint showing the href
Images, headings, lists, and checkboxes map to proper accessibility roles
Caching & Reliability
LRU DOM cache (50 entries) keyed on html + allowDangerousHtml + ignoredTags to prevent poisoning
LRU image dimension cache (200 entries) avoids repeated Image.getSize() network calls
Per-node error boundary — a failing tag skips but the rest of the tree renders
Top-level ErrorBoundary as final safety net; onError callback for observability
Debug mode emits console logs with tag name and stack trace for each caught error
Developer Experience
Hooks: useHtmlParser, useContentWidth, useTagStyle, useHtmlRendererContext
~118 Jest tests across 7 suites — parser, sanitize, cache, styles, accessibility, renderer, utils
Turborepo monorepo with Lefthook git hooks and release-it + conventional changelog
react-native-builder-bob pipeline producing ESM module + TypeScript declarations
Example app on RN 0.84 / React 19 demonstrates every feature end-to-end

Other Projects

View All →
Arkmantra
Ayurvedic Cosmetics E-Commerce Storefront & Admin

A highly hardened, full-featured D2C storefront and admin control panel designed...

Soul33 – The Beacon
Spirituality, Meditation & Mindfulness Platform

A cross-platform spiritual wellness app live on iOS & Android with Free, Seeker ...

Yoke Yoga
Social Wellness, Live Yoga & Learning Platform

Production yoga social platform — TikTok-style Reels, ZEGOCLOUD live streaming +...