Markdown rendering and editing primitives for React Native, running only in JS. No native code needed.
@ronradtke/react-native-markdown-display turns markdown into real React Native views, not a WebView. It pairs a typed markdown viewer with optional input and composer components, so the same package can power read-only content, message previews, documentation screens, and markdown authoring flows.
- ⚡ Native rendering pipeline: markdown is parsed with
markdown-it, normalized into an AST, and rendered with React Native components. - 🧱 No WebView dependency: content participates in your React Native layout, styling, theming, navigation, and event handling.
- 🧩 Typed customization surface: override styles, render rules, link handling, parser behavior, and image handling with TypeScript-friendly APIs.
- ✍️ Viewer and editor pieces: use
<Markdown>for display,MarkdownStreamfor streaming text, orMarkdownTextInput/MarkdownComposerfor authoring. - 🔌 Extensible markdown support: bring your own
markdown-itinstance or opt into bundled plugins such as underline.
This package is intended as a modern replacement for react-native-markdown-renderer, with stricter typing and a maintained native rendering architecture.
yarn add @ronradtke/react-native-markdown-displaynpm install @ronradtke/react-native-markdown-displayimport React from 'react';
import {SafeAreaView, ScrollView} from 'react-native';
import Markdown from '@ronradtke/react-native-markdown-display';
const value = `
# Hello
This is **markdown** rendered with native React Native components.
`;
export default function App(): React.JSX.Element {
return (
<SafeAreaView>
<ScrollView>
<Markdown>{value}</Markdown>
</ScrollView>
</SafeAreaView>
);
}import React from 'react';
import {SafeAreaView, View} from 'react-native';
import Markdown, {MarkdownComposer} from '@ronradtke/react-native-markdown-display';
export default function App(): React.JSX.Element {
const [value, setValue] = React.useState('## Draft message');
return (
<SafeAreaView>
<View style={{flex: 1, gap: 16, padding: 16}}>
<MarkdownComposer onChangeText={setValue} previewEnabled value={value} />
<Markdown>{value}</Markdown>
</View>
</SafeAreaView>
);
}| Use case | Component |
|---|---|
| 📖 Render markdown content | <Markdown> |
| ⏱️ Render actively streaming markdown text | MarkdownStream |
| ⌨️ Add a markdown-aware text input | MarkdownTextInput |
| 🧰 Ship an opinionated markdown composer with toolbar and preview | MarkdownComposer |
| 🔎 Preview an editor value with the same renderer | MarkdownPreview |
The default parser supports common markdown content including:
- headings, paragraphs, horizontal rules, and blockquotes
- bold, italic, strikethrough, inline code, and links
- ordered and unordered lists
- fenced and indented code blocks
- tables
- images with configurable URL handlers
- typographer replacements from
markdown-it
You can extend or restrict the syntax by passing a custom markdown-it instance through the markdownit prop. Underline support is included as an opt-in plugin via createMarkdownIt({underline: true}) or underlinePlugin.
The viewer is designed to be customized at the right layer:
- 🎨 use
stylefor visual changes - 🧬 use
ruleswhen a markdown node should render differently - 🔗 use
onLinkPressto control navigation - ⚙️ use
markdownitto change parsing behavior - 🖼️ use
allowedImageHandlersanddefaultImageHandlerto control image sources - 🧭 use
debugPrintTreeto inspect the AST while integrating custom syntax
- Viewer guide: rendering, styles, custom rules,
MarkdownIt, preprocessing, and streaming - Input guide:
MarkdownTextInput,MarkdownComposer, toolbars, prompts, shortcuts, and previews - Editor architecture note: internal editor model and design notes
- Example app: local example project
MIT