npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nanogiants/react-native-render-html

v1.0.6

Published

A lightweight, customisable HTML renderer for React Native

Readme

@nanogiants/react-native-render-html

A lightweight, customisable HTML renderer for React Native.

Parses an HTML string and maps each recognised element to the appropriate React Native primitive — no native modules, no WebView. Images and text components are injected via render props, keeping the package free of any hard image-library dependency.


Installation

npm install @nanogiants/react-native-render-html
# or
yarn add @nanogiants/react-native-render-html
# or
pnpm add @nanogiants/react-native-render-html

react and react-native are peer dependencies and must already be present in your project.


Quick start

import { RenderHTML } from '@nanogiants/react-native-render-html';
import { Image } from 'react-native';

const html = `
  <h1>Hello world</h1>
  <p>This is a <strong>bold</strong> statement.</p>
  <img src="https://picsum.photos/400/200" />
`;

export default function Screen() {
  return (
    <RenderHTML
      html={html}
      renderImage={(props) => <Image {...props} />}
      baseStyle={{ fontSize: 16, lineHeight: 24, color: '#111' }}
      onLinkPress={({ url }) => Linking.openURL(url)}
    />
  );
}

Props

html (required)

html: string

The HTML string to parse and render.


renderImage

renderImage?: (props: ImageProps) => ReactNode

Render prop invoked for every image in the output: <img> tags and unordered-list bullet markers. Receives standard React Native ImageProps (source, style, alt, …).

When omitted the built-in React Native <Image> component is used.

// Using expo-image for better caching
import { Image } from 'expo-image';

<RenderHTML
  html={html}
  renderImage={(props) => <Image {...props} contentFit="contain" />}
/>

renderTextComponent

renderTextComponent?: (props: TextProps) => ReactNode

Render prop invoked for every text node. Receives standard React Native TextProps. Use this to swap in a custom typography component.

<RenderHTML
  html={html}
  renderTextComponent={(props) => <MyAppText {...props} />}
/>

baseStyle

baseStyle?: TextStyle

Base text style applied to all elements before per-tag overrides. Commonly used to set a global font family, size, line height, or colour.


tagStyles

tagStyles?: Partial<TagStyles>

Per-tag style overrides. Each key is an HTML tag name; the value is { text?: TextStyle; block?: ViewStyle }.

<RenderHTML
  html={html}
  tagStyles={{
    h1: { text: { color: 'navy' } },
    blockquote: { block: { borderLeftColor: '#6366f1' } },
    code: { text: { fontFamily: 'JetBrainsMono' } },
    section: { block: { marginVertical: 16 } },
  }}
/>

classesStyles

classesStyles?: { [className: string]: { text?: TextStyle; block?: ViewStyle } }

Style overrides keyed by HTML class attribute value. Applied on top of the matching tag style.

<RenderHTML
  html='<p class="lead">Introduction paragraph</p>'
  classesStyles={{
    lead: { text: { fontSize: 20, fontWeight: '600' } },
  }}
/>

listGap

listGap?: number

Vertical gap between items in <ul> and <ol> lists. Maps to the flex gap property. Defaults to 0.


onLinkPress

onLinkPress?: (options: { url: string; title: string }) => void

Called when the user taps an <a> element.

import { Linking } from 'react-native';

<RenderHTML
  html={html}
  onLinkPress={({ url }) => Linking.openURL(url)}
/>

markerColor

markerColor?: string

Colour of bullet markers in unordered lists. Falls back to the inherited text colour, then 'pink'.


renderLinkIcon

renderLinkIcon?: (href: string, style: ImageStyle) => ReactNode

Render prop called for every <a> element. Receives the raw href string and a pre-computed ImageStyle sized and tinted to match the surrounding text (height, width, tintColor, paddingTop).

Return a node to display an icon after the link text, or null/undefined to show nothing. When this prop is omitted no icon is rendered.

import { Image } from 'expo-image';

<RenderHTML
  html={html}
  renderLinkIcon={(href, style) => {
    const isExternal = href.startsWith('http://') || href.startsWith('https://');
    if (!isExternal) return null;
    return <Image source={{ uri: MY_EXTERNAL_ICON_URI }} style={style} contentFit="contain" />;
  }}
/>

Supported HTML tags

| Category | Tags | |---|---| | Headings | h1 h2 h3 h4 h5 h6 | | Sectioning | main section article aside nav header footer | | Text block | p blockquote pre div | | Inline | a b strong i em u s del mark small sup sub span code | | Lists | ul ol li dl dt dd | | Media | img | | Table | table thead tbody tfoot tr th td | | Other | hr br |

Unknown tags (e.g. script, style, iframe) are silently ignored.


Default styles

The renderer ships with sensible defaults for all supported tags. Every default can be overridden via tagStyles.

| Tag | Default | |---|---| | h1 | 32px, line-height 38.4, top/bottom margin | | h2 | 24px, line-height 28.8, top/bottom margin | | h3 | 18.72px, matching margin | | h4–h6 | Scaled down accordingly | | p | marginTop: 8 / marginBottom: 8 (collapsed at container edges) | | a | Underlined; optional icon via renderLinkIcon | | blockquote | Italic, 4px left border, grey background | | pre / code | Monospace font, grey background | | ul / ol | paddingLeft: 12, configurable gap | | b / strong | Bold | | i / em | Italic | | u | Underline | | s / del | Strikethrough | | mark | backgroundColor: '#fff59d' | | small | max(baseSize − 2, 12) | | sup / sub | max(baseSize − 4, 10), aligned top/bottom | | hr | 1px bottom border, marginVertical: 12 | | img | flex: 1, height: 100, marginVertical: 8; aspect ratio corrected after async Image.getSize | | th | Bold, padding: 8, 1px border | | td | padding: 8 | | section / article | marginVertical: 8 | | header | marginBottom: 8 | | footer | marginTop: 8 | | main / aside / nav | No default margin (semantic wrappers) |


Known issues

The following elements are partially supported but do not yet render correctly in all cases:

| Tag | Issue | |---|---| | sub | Vertical offset relies on textAlignVertical, which is Android-only. No visual offset on iOS. | | sup | Same as sub — no visual offset on iOS. | | code | Rendered as an inline <Text> span. When used outside a <pre> block, padding and background may bleed into surrounding text or be clipped by the parent <Text>. | | pre | Newlines and whitespace are not preserved. The HTML source has all newlines stripped before parsing, and all remaining whitespace is collapsed during text-node rendering. Code blocks appear as a single unwrapped line. |


License

Apache 2.0 — see LICENSE for details.